import pytest

from aliro_harness.reader.auth0 import build_auth0_apdu, build_auth0_data


def test_auth0_data_field_carries_six_mandatory_tlvs_in_spec_order():
    reader_ephem_uncomp = bytes([0x04]) + b"\x11" * 32 + b"\x22" * 32
    data = build_auth0_data(
        reader_ephem_pub_uncompressed=reader_ephem_uncomp,
        reader_group_id=b"\xaa" * 16,
        reader_group_sub_id=b"\xbb" * 16,
        transaction_id=b"\xcc" * 16,
        command_parameters=0x00,
        authentication_policy=0x00,
    )
    assert data[0:3] == bytes([0x41, 0x01, 0x00])     # command_parameters
    assert data[3:6] == bytes([0x42, 0x01, 0x00])     # authentication_policy
    assert data[6:10] == bytes([0x5C, 0x02, 0x01, 0x00])  # protocol_version
    assert data[10:12] == bytes([0x87, 0x41])         # reader_ePubK header (65B)
    assert data[12:77] == reader_ephem_uncomp
    assert data[77:79] == bytes([0x4C, 0x10])         # transaction_id header
    assert data[79:95] == b"\xcc" * 16
    assert data[95:97] == bytes([0x4D, 0x20])         # reader_identifier (32B = group||sub)
    assert data[97:113] == b"\xaa" * 16
    assert data[113:129] == b"\xbb" * 16
    assert len(data) == 129


def test_build_auth0_apdu_wraps_data_in_short_form():
    apdu = build_auth0_apdu(b"\x41\x01\x00")
    assert apdu == bytes([0x80, 0x80, 0x00, 0x00, 0x03, 0x41, 0x01, 0x00])


def test_reader_ephem_must_be_uncompressed():
    with pytest.raises(ValueError, match="65B uncompressed"):
        build_auth0_data(
            reader_ephem_pub_uncompressed=b"\x02" + b"\x11" * 32,  # compressed
            reader_group_id=b"\xaa" * 16,
            reader_group_sub_id=b"\xbb" * 16,
            transaction_id=b"\xcc" * 16,
        )


def test_wrong_group_id_length_rejected():
    with pytest.raises(ValueError, match="must each be 16B"):
        build_auth0_data(
            reader_ephem_pub_uncompressed=bytes([0x04]) + b"\x11" * 32 + b"\x22" * 32,
            reader_group_id=b"\xaa" * 15,
            reader_group_sub_id=b"\xbb" * 16,
            transaction_id=b"\xcc" * 16,
        )


def test_wrong_transaction_id_length_rejected():
    with pytest.raises(ValueError, match="must be 16B"):
        build_auth0_data(
            reader_ephem_pub_uncompressed=bytes([0x04]) + b"\x11" * 32 + b"\x22" * 32,
            reader_group_id=b"\xaa" * 16,
            reader_group_sub_id=b"\xbb" * 16,
            transaction_id=b"\xcc" * 17,
        )


def test_command_parameters_bit_zero_set_emits_0x01_byte():
    data = build_auth0_data(
        reader_ephem_pub_uncompressed=bytes([0x04]) + b"\x11" * 32 + b"\x22" * 32,
        reader_group_id=b"\xaa" * 16,
        reader_group_sub_id=b"\xbb" * 16,
        transaction_id=b"\xcc" * 16,
        command_parameters=0x01,
    )
    assert data[0:3] == bytes([0x41, 0x01, 0x01])
