"""APDU constructor tests — exact byte-shape locks."""

import pytest

from aliro_harness.personalizer.apdus import (
    CLA_PROPRIETARY,
    INS_COMMIT,
    INS_SET_CRED_ISSUER_PUBK,
    INS_SET_CRED_PRIV,
    INS_SET_CRED_PUBK,
    INS_SET_READER_PUBK,
    PROVISIONING_AID,
    commit_apdu,
    select_provisioning_apdu,
    set_credential_issuer_pubk_apdu,
    set_credential_priv_apdu,
    set_credential_pubk_apdu,
    set_reader_pubk_apdu,
)


def test_provisioning_aid_matches_applet_constant():
    """If this changes, AliroAids.PROVISIONING in the applet has drifted."""
    assert PROVISIONING_AID.hex().upper() == "A000000909ACCE559901"


def test_select_provisioning_apdu_shape():
    apdu = select_provisioning_apdu()
    assert apdu == bytes([0x00, 0xA4, 0x04, 0x00, 0x0A]) + PROVISIONING_AID


def test_set_credential_priv_apdu():
    priv = bytes(range(32))
    apdu = set_credential_priv_apdu(priv)
    assert apdu == bytes([CLA_PROPRIETARY, INS_SET_CRED_PRIV, 0x00, 0x00, 0x20]) + priv


def test_set_credential_priv_rejects_wrong_length():
    with pytest.raises(ValueError, match="32B"):
        set_credential_priv_apdu(bytes(31))


def test_set_credential_pubk_apdu():
    pub = bytes(range(64))
    apdu = set_credential_pubk_apdu(pub)
    assert apdu == bytes([CLA_PROPRIETARY, INS_SET_CRED_PUBK, 0x00, 0x00, 0x40]) + pub


def test_set_credential_pubk_rejects_wrong_length():
    with pytest.raises(ValueError, match="64B"):
        set_credential_pubk_apdu(bytes(65))


def test_set_reader_pubk_apdu():
    pub = bytes(range(64))
    apdu = set_reader_pubk_apdu(pub)
    assert apdu == bytes([CLA_PROPRIETARY, INS_SET_READER_PUBK, 0x00, 0x00, 0x40]) + pub


def test_set_credential_issuer_pubk_apdu():
    pub = bytes(range(64))
    apdu = set_credential_issuer_pubk_apdu(pub)
    # CLA INS P1 P2 Lc data — INS 0x25, same 64B x||y shape as cred_pubk
    assert apdu == bytes([CLA_PROPRIETARY, INS_SET_CRED_ISSUER_PUBK, 0x00, 0x00, 0x40]) + pub


def test_set_credential_issuer_pubk_rejects_wrong_length():
    with pytest.raises(ValueError, match="64B"):
        set_credential_issuer_pubk_apdu(bytes(63))


def test_ins_set_cred_issuer_pubk_constant_matches_applet():
    """Lock-down: applet PersonalizationApplet.INS_SET_CREDENTIAL_ISSUER_PUBK = 0x25."""
    assert INS_SET_CRED_ISSUER_PUBK == 0x25


def test_commit_apdu_has_no_data_field():
    apdu = commit_apdu()
    assert apdu == bytes([CLA_PROPRIETARY, INS_COMMIT, 0x00, 0x00])
    assert len(apdu) == 4
