"""
LockStock Core Types
--------------------
Shared types for all SDK integrations.
"""

from dataclasses import dataclass, field
from typing import List, Optional, Dict, Any
from enum import Enum


class VerifyStatus(str, Enum):
    ACCEPTED = "accepted"
    REJECTED = "rejected"
    BUFFERED = "buffered"


@dataclass
class VerifyResult:
    """Result of a capability verification request."""
    status: VerifyStatus
    reason: Optional[str] = None
    state_hash: Optional[str] = None
    sequence: Optional[int] = None
    server_timestamp: Optional[int] = None

    @property
    def authorized(self) -> bool:
        return self.status == VerifyStatus.ACCEPTED


@dataclass
class AuditEntry:
    """An entry in the agent's audit trail."""
    sequence: int
    action: str
    timestamp: int
    state_hash: str
    signature: str
    metadata: Dict[str, Any] = field(default_factory=dict)


@dataclass
class AgentCard:
    """Agent identity and capabilities."""
    agent_id: str
    display_name: str
    capabilities: List[str]
    status: str = "active"
    fingerprint: Optional[str] = None
    owner_id: Optional[str] = None
    created_at: Optional[str] = None

    def has_capability(self, capability: str) -> bool:
        """Check if agent has a specific capability."""
        return capability.upper() in [c.upper() for c in self.capabilities]


# Mapping from common tool names to LockStock capabilities
# These map to the Task enum variants in Rust (case-insensitive)
TOOL_CAPABILITY_MAP = {
    # File operations -> FileRead, FileWrite
    "read": "FILEREAD",
    "read_file": "FILEREAD",
    "Read": "FILEREAD",
    "Glob": "FILEREAD",
    "glob": "FILEREAD",
    "Grep": "FILEREAD",
    "grep": "FILEREAD",
    "write": "FILEWRITE",
    "write_file": "FILEWRITE",
    "Write": "FILEWRITE",
    "edit": "FILEWRITE",
    "Edit": "FILEWRITE",
    "NotebookEdit": "FILEWRITE",

    # Shell/execution -> Shell (alias for Deploy)
    "bash": "SHELL",
    "Bash": "SHELL",
    "shell": "SHELL",
    "execute": "SHELL",
    "run_command": "SHELL",
    "KillShell": "SHELL",

    # Network operations -> Network
    "web_fetch": "NETWORK",
    "WebFetch": "NETWORK",
    "web_search": "NETWORK",
    "WebSearch": "NETWORK",
    "http_request": "NETWORK",
    "fetch": "NETWORK",

    # Database operations -> Database
    "sql": "DATABASE",
    "query": "DATABASE",
    "db_read": "DATABASE",
    "db_write": "DATABASE",
    "LSP": "DATABASE",  # Language Server Protocol reads code

    # Agent operations -> Teleport, Handoff
    "task": "TELEPORT",
    "Task": "TELEPORT",
    "spawn_agent": "TELEPORT",
    "TaskOutput": "TELEPORT",
    "handoff": "HANDOFF",
    "delegate": "DELEGATE",

    # State operations -> Checkpoint, Teleport
    "checkpoint": "CHECKPOINT",
    "save_state": "CHECKPOINT",
    "export_passport": "TELEPORT",
    "import_passport": "TELEPORT",

    # Monitoring -> Heartbeat
    "heartbeat": "HEARTBEAT",
    "health_check": "HEARTBEAT",

    # Operations -> Deploy, Restart, Backup, Rollback
    "deploy": "DEPLOY",
    "restart": "RESTART",
    "backup": "BACKUP",
    "rollback": "ROLLBACK",

    # Task management tools
    "TaskCreate": "FILEWRITE",
    "TaskUpdate": "FILEWRITE",
    "TaskList": "FILEREAD",
    "TaskGet": "FILEREAD",

    # Skills
    "Skill": "SHELL",
    "AskUserQuestion": "HEARTBEAT",  # Interactive, low privilege
    "EnterPlanMode": "HEARTBEAT",
    "ExitPlanMode": "HEARTBEAT",
}


def map_tool_to_capability(tool_name: str) -> str:
    """Map a tool name to a LockStock capability."""
    return TOOL_CAPABILITY_MAP.get(tool_name, "UNKNOWN")


# Prime field modulus (F_65537)
MODULUS = 65537


class Matrix:
    """2x2 matrix over F_65537 for topological state transitions."""

    def __init__(self, a11: int, a12: int, a21: int, a22: int):
        self.a11 = a11 % MODULUS
        self.a12 = a12 % MODULUS
        self.a21 = a21 % MODULUS
        self.a22 = a22 % MODULUS

    def multiply(self, other: "Matrix") -> "Matrix":
        """Matrix multiplication in F_65537."""
        return Matrix(
            (self.a11 * other.a11 + self.a12 * other.a21) % MODULUS,
            (self.a11 * other.a12 + self.a12 * other.a22) % MODULUS,
            (self.a21 * other.a11 + self.a22 * other.a21) % MODULUS,
            (self.a21 * other.a12 + self.a22 * other.a22) % MODULUS,
        )

    def to_dict(self) -> Dict[str, int]:
        """Convert to dictionary for JSON serialization."""
        return {"a11": self.a11, "a12": self.a12, "a21": self.a21, "a22": self.a22}

    @classmethod
    def from_dict(cls, d: Dict[str, int]) -> "Matrix":
        """Create from dictionary."""
        return cls(d.get("a11", 1), d.get("a12", 0), d.get("a21", 0), d.get("a22", 1))

    @classmethod
    def identity(cls) -> "Matrix":
        """Return identity matrix."""
        return cls(1, 0, 0, 1)


# Generator matrices for each task (matching Rust server)
GENERATOR_MATRICES = {
    "DEPLOY": Matrix(1, 1, 0, 1),
    "RESTART": Matrix(1, 0, 1, 1),
    "BACKUP": Matrix(2, 1, 1, 1),
    "ROLLBACK": Matrix(1, 1, 1, 2),
    "HEARTBEAT": Matrix(0, 65536, 1, 0),  # 90-degree rotation
    "CHECKPOINT": Matrix(2, 1, 1, 2),
    "TELEPORT": Matrix(3, 1, 1, 1),
    "FILEREAD": Matrix(1, 2, 0, 1),
    "FILEWRITE": Matrix(1, 3, 0, 1),
    "NETWORK": Matrix(1, 0, 2, 1),
    "SHELL": Matrix(1, 4, 0, 1),  # Upper triangular (distinct from Deploy, v1.0.8+)
    "DATABASE": Matrix(1, 0, 3, 1),
    "CHATCOMPLETION": Matrix(1, 5, 0, 1),  # LLM inference (request)
    "CHATCOMPLETIONRESPONSE": Matrix(1, 6, 0, 1),  # LLM inference (response)
    "HANDOFF": Matrix(3, 2, 1, 1),
    "DELEGATE": Matrix(1, 1, 2, 3),
    "ALL": Matrix(1, 0, 0, 1),  # Identity
}


def get_generator(task: str) -> Matrix:
    """Get the generator matrix for a task."""
    return GENERATOR_MATRICES.get(task.upper(), Matrix.identity())
