"""Agent package model and operations."""

from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path

import yaml

from ievo.core.deps import McpDependency, PluginDependency


@dataclass
class AgentModel:
    """Model routing configuration."""

    primary: str = "sonnet"
    fallback: str = "haiku"


DEFAULT_ALLOWED_TOOLS = ["Read", "Write", "Edit", "Glob", "Grep"]


@dataclass
class SandboxConfig:
    """Docker sandbox configuration for agent execution."""

    allowed_tools: list[str] = field(default_factory=lambda: list(DEFAULT_ALLOWED_TOOLS))
    network: bool = False
    memory_mb: int = 2048
    cpu_limit: float = 2.0
    timeout_seconds: int = 3600


@dataclass
class AgentDisclosure:
    """Progressive disclosure tiers (tokens)."""

    metadata: int = 100
    instructions: int = 400
    resources: int = 600


@dataclass
class AgentHooks:
    """Lifecycle hooks."""

    on_install: str | None = None
    on_session_start: str | None = "load_memory"
    on_session_end: str | None = "save_memory"
    on_error: str | None = "evo_analyze"


@dataclass
class AgentPackage:
    """Represents an agent.yaml manifest."""

    name: str
    version: str = "0.1.0"
    description: str = ""
    author: str = ""
    model: AgentModel = field(default_factory=AgentModel)
    dependencies: list[str] = field(default_factory=list)
    mcp: list[McpDependency] = field(default_factory=list)
    plugins: list[PluginDependency] = field(default_factory=list)
    skills: list[str] = field(default_factory=lambda: ["evo"])
    hooks: AgentHooks = field(default_factory=AgentHooks)
    disclosure: AgentDisclosure = field(default_factory=AgentDisclosure)
    sandbox: SandboxConfig = field(default_factory=SandboxConfig)

    @classmethod
    def load(cls, agent_dir: Path) -> AgentPackage:
        """Load agent.yaml from a directory."""
        path = agent_dir / "agent.yaml"
        if not path.exists():
            msg = f"agent.yaml not found in {agent_dir}"
            raise FileNotFoundError(msg)

        data = yaml.safe_load(path.read_text())

        model_data = data.get("model", {})
        hooks_data = data.get("hooks", {})
        disclosure_data = data.get("disclosure", {})
        sandbox_data = data.get("sandbox", {})

        return cls(
            name=data["name"],
            version=data.get("version", "0.1.0"),
            description=data.get("description", ""),
            author=data.get("author", ""),
            model=AgentModel(
                primary=model_data.get("primary", "sonnet"),
                fallback=model_data.get("fallback", "haiku"),
            ),
            dependencies=data.get("dependencies", []),
            mcp=[McpDependency.from_dict(m) for m in data.get("mcp", [])],
            plugins=[PluginDependency.from_dict(p) for p in data.get("plugins", [])],
            skills=data.get("skills", ["evo"]),
            hooks=AgentHooks(
                on_install=hooks_data.get("on_install"),
                on_session_start=hooks_data.get("on_session_start", "load_memory"),
                on_session_end=hooks_data.get("on_session_end", "save_memory"),
                on_error=hooks_data.get("on_error", "evo_analyze"),
            ),
            disclosure=AgentDisclosure(
                metadata=disclosure_data.get("metadata", 100),
                instructions=disclosure_data.get("instructions", 400),
                resources=disclosure_data.get("resources", 600),
            ),
            sandbox=SandboxConfig(
                allowed_tools=sandbox_data.get("allowed_tools", list(DEFAULT_ALLOWED_TOOLS)),
                network=sandbox_data.get("network", False),
                memory_mb=sandbox_data.get("memory_mb", 2048),
                cpu_limit=sandbox_data.get("cpu_limit", 2.0),
                timeout_seconds=sandbox_data.get("timeout_seconds", 3600),
            ),
        )

    def save(self, agent_dir: Path) -> None:
        """Write agent.yaml to a directory."""
        agent_dir.mkdir(parents=True, exist_ok=True)
        data = {
            "name": self.name,
            "version": self.version,
            "description": self.description,
            "author": self.author,
            "model": {"primary": self.model.primary, "fallback": self.model.fallback},
            "dependencies": self.dependencies,
            "mcp": [m.to_dict() for m in self.mcp],
            "plugins": [p.to_dict() for p in self.plugins],
            "skills": self.skills,
            "hooks": {
                "on_install": self.hooks.on_install,
                "on_session_start": self.hooks.on_session_start,
                "on_session_end": self.hooks.on_session_end,
                "on_error": self.hooks.on_error,
            },
            "disclosure": {
                "metadata": self.disclosure.metadata,
                "instructions": self.disclosure.instructions,
                "resources": self.disclosure.resources,
            },
            "sandbox": {
                "allowed_tools": self.sandbox.allowed_tools,
                "network": self.sandbox.network,
                "memory_mb": self.sandbox.memory_mb,
                "cpu_limit": self.sandbox.cpu_limit,
                "timeout_seconds": self.sandbox.timeout_seconds,
            },
        }
        path = agent_dir / "agent.yaml"
        path.write_text(yaml.dump(data, default_flow_style=False, sort_keys=False))
