"""Knowledge bundle for P2P sharing."""

from __future__ import annotations

import hashlib
import json
import time
from dataclasses import asdict, dataclass, field
from typing import Any


@dataclass
class KnowledgeBundle:
    """Self-contained knowledge package for peer-to-peer transfer."""

    bundle_id: str = ""
    source_device_id: str = ""
    created_at: int = 0

    memories: list[dict[str, Any]] = field(default_factory=list)
    entities: list[dict[str, Any]] = field(default_factory=list)
    relationships: list[dict[str, Any]] = field(default_factory=list)
    concepts: list[dict[str, Any]] = field(default_factory=list)

    checkpoint_id: str = ""
    signature: str = ""

    def __post_init__(self) -> None:
        if not self.bundle_id:
            self.bundle_id = hashlib.sha256(
                f"{self.source_device_id}:{time.time_ns()}".encode("utf-8")
            ).hexdigest()[:16]
        if not self.created_at:
            self.created_at = int(time.time() * 1000)

    def to_dict(self) -> dict[str, Any]:
        return asdict(self)

    def to_msgpack(self) -> bytes:
        """Serialize bundle to MessagePack, with JSON fallback."""
        payload = self.to_dict()
        try:
            import msgpack

            return msgpack.packb(payload, use_bin_type=True)
        except Exception:
            return json.dumps(payload, separators=(",", ":")).encode("utf-8")

    @classmethod
    def from_msgpack(cls, data: bytes) -> "KnowledgeBundle":
        """Deserialize MessagePack/JSON encoded bundle."""
        try:
            import msgpack

            payload = msgpack.unpackb(data, raw=False)
        except Exception:
            payload = json.loads(data.decode("utf-8"))
        return cls(**payload)

    def sign(self, private_key: Any) -> None:
        """Sign bundle metadata with Ed25519 private key."""
        content = self._signature_payload()
        signature = private_key.sign(content)
        self.signature = signature.hex()

    def verify(self, public_key: Any) -> bool:
        """Verify bundle signature with Ed25519 public key."""
        if not self.signature:
            return False
        try:
            public_key.verify(bytes.fromhex(self.signature), self._signature_payload())
            return True
        except Exception:
            return False

    def _signature_payload(self) -> bytes:
        # Sign only deterministic metadata so large bundles are fast to verify.
        payload = {
            "bundle_id": self.bundle_id,
            "source": self.source_device_id,
            "created_at": self.created_at,
            "checkpoint_id": self.checkpoint_id,
            "counts": {
                "memories": len(self.memories),
                "entities": len(self.entities),
                "relationships": len(self.relationships),
                "concepts": len(self.concepts),
            },
        }
        return json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
