import ctypes

from pybusmonitor1553.core.dispatcher import MessageDispatcher
from pybusmonitor1553.lib1553.headers import (
    UDP1553Header,
    UDP1553MessageHeader,
    CommandWordUnion,
)
from pybusmonitor1553.lib1553.constants import Subaddress


def test_registry_contains_a1():
    disp = MessageDispatcher()
    key = (Subaddress.RX_SETTINGS, False)
    assert key in disp._registry
    cls = disp._registry[key]
    assert cls.__name__ == "MsgA1"


def test_parse_valid_a1_packet():
    disp = MessageDispatcher()

    # Build command word for A1 (Subaddress = RX_SETTINGS, transmit=False)
    cw = CommandWordUnion(rt_addr=0, sub_addr=int(Subaddress.RX_SETTINGS), word_count=0, transmit=False)
    msg_hdr = UDP1553MessageHeader(command_word_union=cw)
    udp_hdr = UDP1553Header()

    # Convert ctypes structs to raw bytes
    header_bytes = ctypes.string_at(ctypes.addressof(udp_hdr), ctypes.sizeof(udp_hdr))
    msg_hdr_bytes = ctypes.string_at(ctypes.addressof(msg_hdr), ctypes.sizeof(msg_hdr))

    # Minimal data payload (64 bytes = 32 words) - all zeros is fine for parsing
    data_bytes = b"\x00" * 64

    raw = header_bytes + msg_hdr_bytes + data_bytes

    h, msg = disp.parse_packet(raw)

    assert h is not None
    assert msg is not None
    assert msg.__class__.__name__ == "MsgA1"


def test_parse_too_short():
    disp = MessageDispatcher()
    h, msg = disp.parse_packet(b"\x00\x01")
    assert h is None and msg is None
