"""Tests for protocol (envelope, codec, types)."""

from a2a_p2p.protocol.codec import decode, encode
from a2a_p2p.protocol.envelope import A2AEnvelope
from a2a_p2p.protocol.types import (
    HelloPayload,
    MessageType,
    PAYLOAD_MODELS,
    TextPayload,
)


class TestEnvelope:
    def test_defaults(self):
        env = A2AEnvelope(type=MessageType.TEXT)
        assert env.version == 1
        assert env.id  # UUID generated
        assert env.timestamp > 0

    def test_signing_material(self):
        env = A2AEnvelope(
            type=MessageType.TEXT,
            payload={"text": "hello"},
        )
        material = env.signing_material()
        assert isinstance(material, bytes)
        assert env.id.encode() in material


class TestCodec:
    def test_roundtrip_text(self):
        env = A2AEnvelope(
            sender_id="a2a:sender",
            recipient_id="a2a:recipient",
            type=MessageType.TEXT,
            payload=TextPayload(text="hello", context="test").model_dump(),
        )
        raw = encode(env)
        decoded = decode(raw)
        assert decoded.sender_id == env.sender_id
        assert decoded.type == MessageType.TEXT
        assert decoded.payload["text"] == "hello"

    def test_roundtrip_hello(self):
        hello = HelloPayload(
            agent_name="Jarvis",
            owner_display_name="Minttu",
            capabilities=["calendar", "memory"],
            introduction="Personal AI assistant",
        )
        env = A2AEnvelope(
            type=MessageType.HELLO,
            payload=hello.model_dump(),
        )
        raw = encode(env)
        decoded = decode(raw)
        h = HelloPayload.model_validate(decoded.payload)
        assert h.agent_name == "Jarvis"
        assert h.capabilities == ["calendar", "memory"]

    def test_roundtrip_empty_payload(self):
        env = A2AEnvelope(type=MessageType.PING)
        raw = encode(env)
        decoded = decode(raw)
        assert decoded.type == MessageType.PING

    def test_in_reply_to(self):
        env = A2AEnvelope(
            type=MessageType.ACK,
            in_reply_to="abc123",
        )
        raw = encode(env)
        decoded = decode(raw)
        assert decoded.in_reply_to == "abc123"


class TestPayloadModels:
    def test_all_types_have_entry(self):
        """Every MessageType should have an entry in PAYLOAD_MODELS."""
        for mt in MessageType:
            assert mt in PAYLOAD_MODELS, f"Missing: {mt}"

    def test_text_payload_validation(self):
        p = TextPayload(text="hello")
        assert p.text == "hello"
        assert p.context == ""

    def test_hello_payload_defaults(self):
        p = HelloPayload(agent_name="Test")
        assert p.protocol_version == 1
        assert p.capabilities == []
