"""
LockStock A2A Protocol Adapter
-------------------------------
Bidirectional adapter between LockStock and A2A protocols.

Uses the thin client pattern - all verification happens server-side via /v1/stamp.
"""

from typing import Dict, Any, Optional, List
import json

from lockstock_core import LockStockClient, AgentCard
from .agent_card import A2AAgentCard, A2ACapability, A2ASecurity, A2AAuthType


class A2AAdapter:
    """
    Adapter for converting between LockStock and A2A protocols.

    Enables LockStock agents to participate in A2A ecosystems
    and A2A agents to be verified through LockStock.
    """

    def __init__(
        self,
        endpoint: str = "https://lockstock-api-i9kp.onrender.com",
        api_key: Optional[str] = None
    ):
        """
        Initialize A2A adapter.

        Args:
            endpoint: LockStock API endpoint
            api_key: API key for authentication (from dashboard)
        """
        self.endpoint = endpoint.rstrip("/")
        self.api_key = api_key

    def to_a2a_card(self, lockstock_card: Dict[str, Any]) -> A2AAgentCard:
        """
        Convert a LockStock agent card to A2A format.

        Args:
            lockstock_card: LockStock internal agent card

        Returns:
            A2A-compatible agent card
        """
        return A2AAgentCard.from_lockstock_card(
            lockstock_card,
            endpoint=self.endpoint
        )

    def from_a2a_card(self, a2a_card: Dict[str, Any]) -> Dict[str, Any]:
        """
        Convert an A2A agent card to LockStock format.

        Args:
            a2a_card: A2A protocol agent card

        Returns:
            LockStock-compatible agent card
        """
        metadata = a2a_card.get("metadata", {})
        capabilities = a2a_card.get("capabilities", [])

        return {
            "agent_id": metadata.get("id", "unknown"),
            "display_name": metadata.get("name", "Unknown Agent"),
            "description": metadata.get("description"),
            "capabilities": [cap.get("name") for cap in capabilities],
            "status": "active",
            "source": "a2a_import",
            "a2a_metadata": {
                "version": a2a_card.get("version"),
                "provider": metadata.get("provider"),
                "security": a2a_card.get("security"),
                "endpoints": a2a_card.get("endpoints")
            }
        }

    def to_a2a_json(self, lockstock_card: Dict[str, Any]) -> str:
        """
        Convert LockStock card to A2A JSON string.

        Args:
            lockstock_card: LockStock agent card

        Returns:
            JSON string in A2A format
        """
        a2a_card = self.to_a2a_card(lockstock_card)
        return a2a_card.to_json()

    def capability_mapping(self) -> Dict[str, str]:
        """
        Get mapping between LockStock capabilities and A2A capability types.

        Returns:
            Dictionary mapping LockStock to A2A capability names
        """
        return {
            # LockStock -> A2A standard capability names
            "DEPLOY": "code_execution",
            "RESTART": "service_management",
            "BACKUP": "data_management",
            "ROLLBACK": "state_management",
            "HEARTBEAT": "health_monitoring",
            "CHECKPOINT": "state_checkpoint",
            "TELEPORT": "agent_migration",

            # Tool-based capabilities
            "FILE_READ": "file_operations",
            "FILE_WRITE": "file_operations",
            "NETWORK": "network_access",
            "SHELL_EXEC": "code_execution"
        }

    def generate_well_known_agent_card(
        self,
        agent_id: str,
        name: str,
        capabilities: List[str],
        description: Optional[str] = None
    ) -> str:
        """
        Generate a well-known agent card for A2A discovery.

        In A2A, agents advertise themselves at:
        https://your-domain.com/.well-known/agent.json

        Args:
            agent_id: Agent identifier
            name: Agent display name
            capabilities: List of capabilities
            description: Optional description

        Returns:
            JSON string suitable for /.well-known/agent.json
        """
        a2a_capabilities = [
            A2ACapability(
                name=cap,
                type="lockstock_verified",
                description=f"LockStock-verified capability: {cap}"
            )
            for cap in capabilities
        ]

        security = A2ASecurity(
            protocol="LockStock-v1",
            auth_type=A2AAuthType.LOCKSTOCK,
            verification_endpoint=f"{self.endpoint}/v1/stamp",
            signing_supported=True
        )

        card = A2AAgentCard(
            agent_id=agent_id,
            name=name,
            description=description or f"LockStock-secured agent: {name}",
            capabilities=a2a_capabilities,
            security=security,
            task_endpoint=f"{self.endpoint}/a2a/task",
            status_endpoint=f"{self.endpoint}/a2a/status/{agent_id}"
        )

        return card.to_json()

    async def verify_a2a_agent(
        self,
        a2a_card: Dict[str, Any],
        capability: str
    ) -> Dict[str, Any]:
        """
        Verify an A2A agent has a claimed capability.

        When an external A2A agent claims to have a capability,
        this stamps it through their declared verification endpoint.

        Args:
            a2a_card: The A2A agent card
            capability: Capability to verify

        Returns:
            Verification result
        """
        security = a2a_card.get("security", {})
        protocol = security.get("protocol", "")

        if protocol == "LockStock-v1":
            # This is a LockStock-secured agent, stamp through our system
            agent_id = a2a_card.get("metadata", {}).get("id")

            if agent_id and self.api_key:
                # Create client to stamp
                client = LockStockClient(
                    agent_id=agent_id,
                    api_key=self.api_key,
                    endpoint=self.endpoint
                )

                result = await client.stamp(task=capability)
                await client.close()

                return {
                    "verified": result.authorized,
                    "protocol": "LockStock-v1",
                    "agent_id": agent_id,
                    "capability": capability,
                    "state_hash": result.state_hash
                }

        # Unknown protocol or missing API key, cannot verify
        return {
            "verified": False,
            "protocol": protocol,
            "reason": f"Cannot verify: protocol={protocol}, api_key={'set' if self.api_key else 'missing'}"
        }
