"""Archetype registry — loads and manages archetypes."""

from __future__ import annotations

from pathlib import Path
from typing import Any

import yaml

from agentguard.archetypes.base import Archetype, _from_dict

_BUILTIN_DIR = Path(__file__).parent / "builtin"


class ArchetypeRegistry:
    """Registry for loading and caching archetypes."""

    def __init__(self) -> None:
        self._archetypes: dict[str, Archetype] = {}
        self._loaded_builtins = False

    def get(self, archetype_id: str) -> Archetype:
        """Get an archetype by ID.

        Raises:
            KeyError: If archetype not found.
        """
        if not self._loaded_builtins:
            self._load_builtins()

        if archetype_id not in self._archetypes:
            raise KeyError(
                f"Archetype '{archetype_id}' not found. "
                f"Available: {list(self._archetypes.keys())}"
            )
        return self._archetypes[archetype_id]

    def register(self, archetype: Archetype) -> None:
        """Register a custom archetype."""
        self._archetypes[archetype.id] = archetype

    def list_available(self) -> list[str]:
        """List available archetype IDs."""
        if not self._loaded_builtins:
            self._load_builtins()
        return sorted(self._archetypes.keys())

    def _load_builtins(self) -> None:
        """Load all YAML archetypes from the builtin directory."""
        self._loaded_builtins = True

        if not _BUILTIN_DIR.exists():
            return

        for yaml_file in _BUILTIN_DIR.glob("*.yaml"):
            data: dict[str, Any] = yaml.safe_load(yaml_file.read_text(encoding="utf-8"))
            archetype = _from_dict(data)
            self._archetypes[archetype.id] = archetype


# Module-level singleton
_default_registry: ArchetypeRegistry | None = None


def get_archetype_registry() -> ArchetypeRegistry:
    """Get the default archetype registry singleton."""
    global _default_registry
    if _default_registry is None:
        _default_registry = ArchetypeRegistry()
    return _default_registry
