"""
AgentMesh protobuf message stubs (Python).

These stubs mirror the ``agentmesh.v1`` protobuf schema defined in
``agentmesh/v1/agentmesh.proto``. They are hand-written dataclasses
that match the field names and types of the generated protobuf messages.

In a production build, these would be replaced by ``buf generate`` output
using ``protoc-gen-python`` or ``betterproto``. Using dataclasses here
preserves type safety and runtime behaviour without requiring the protobuf
compiler at install time.
"""

from __future__ import annotations

from dataclasses import dataclass, field


@dataclass
class AgentMeshPacket:
    """Core mesh packet — all inter-agent messages use this envelope.

    Mirrors ``agentmesh.v1.AgentMeshPacket`` from the .proto schema.

    Attributes:
        id: Unique packet ID (per-sender monotonic uint32).
        from_: Sender agent ID.
        to: Recipient agent ID or broadcast wildcard.
        hop_limit: Maximum number of hops before packet is dropped.
        hop_start: Current hop count.
        portnum: Application port number.
        payload: Raw message payload bytes.
        want_ack: Whether the sender expects an acknowledgement.
        timestamp: Packet creation timestamp (milliseconds since epoch).
        channel: Routing channel identifier.
        meta: Arbitrary key-value metadata.
        idempotency_key: Deduplication key for exactly-once delivery.
        next_hop: Next-hop agent ID for explicit routing.
    """

    id: int = 0
    from_: str = ""
    to: str = ""
    hop_limit: int = 3
    hop_start: int = 0
    portnum: int = 0
    payload: bytes = b""
    want_ack: bool = False
    timestamp: int = 0
    channel: str = ""
    meta: dict[str, str] = field(default_factory=dict)
    idempotency_key: str = ""
    next_hop: str = ""

    def SerializeToString(self) -> bytes:
        """Serialise to a minimal binary format for wire transmission.

        For full protobuf binary compatibility, use buf-generated stubs.
        This implementation produces a JSON-encoded bytes payload prefixed
        with the packet ID for debugging and testing.
        """
        import json
        import struct
        body = json.dumps({
            "id": self.id,
            "from": self.from_,
            "to": self.to,
            "payload": list(self.payload),
            "channel": self.channel,
            "idempotencyKey": self.idempotency_key,
        }).encode("utf-8")
        return struct.pack("<I", self.id) + body

    @classmethod
    def FromString(cls, data: bytes) -> "AgentMeshPacket":
        """Deserialise from the minimal binary format.

        Args:
            data: Bytes as produced by ``SerializeToString``.

        Returns:
            Parsed ``AgentMeshPacket`` instance.
        """
        import json
        import struct
        if len(data) < 4:
            return cls()
        packet_id = struct.unpack("<I", data[:4])[0]
        body = json.loads(data[4:].decode("utf-8"))
        return cls(
            id=packet_id,
            from_=body.get("from", ""),
            to=body.get("to", ""),
            payload=bytes(body.get("payload", [])),
            channel=body.get("channel", ""),
            idempotency_key=body.get("idempotencyKey", ""),
        )


@dataclass
class AgentCard:
    """Agent capability advertisement.

    Mirrors ``agentmesh.v1.AgentCard``.

    Attributes:
        agent_id: Unique agent identifier (DID).
        name: Human-readable agent name.
        role: Agent role string.
        capabilities: List of capability identifiers.
        skills: List of skill identifiers.
        status: Current agent status.
        last_seen: Last heartbeat timestamp (ms since epoch).
        version: Agent software version string.
        meta: Arbitrary key-value metadata.
    """

    agent_id: str = ""
    name: str = ""
    role: str = ""
    capabilities: list[str] = field(default_factory=list)
    skills: list[str] = field(default_factory=list)
    status: str = "offline"
    last_seen: int = 0
    version: str = ""
    meta: dict[str, str] = field(default_factory=dict)


@dataclass
class AckPacket:
    """Acknowledgement for a delivered packet.

    Mirrors ``agentmesh.v1.AckPacket``.

    Attributes:
        original_id: ID of the packet being acknowledged.
        from_: Sender of the ack.
        to: Original sender of the packet.
        success: Whether delivery succeeded.
        error: Error message if ``success`` is False.
    """

    original_id: int = 0
    from_: str = ""
    to: str = ""
    success: bool = True
    error: str = ""


@dataclass
class Heartbeat:
    """Periodic liveness signal from an agent.

    Mirrors ``agentmesh.v1.Heartbeat``.

    Attributes:
        agent_id: Agent sending the heartbeat.
        timestamp: Heartbeat timestamp (ms since epoch).
        load: Current CPU/GPU load (0.0–1.0).
        queue_depth: Number of pending tasks.
        uptime: Agent uptime in milliseconds.
    """

    agent_id: str = ""
    timestamp: int = 0
    load: float = 0.0
    queue_depth: int = 0
    uptime: int = 0
