"""Registry for declarative custom agent classes and factories."""
from __future__ import annotations

from typing import Any, Callable


class AgentClassRegistry:
    """Global registry of named Agent subclasses."""

    def __init__(self) -> None:
        self._entries: dict[str, type[Any]] = {}

    def register(self, name: str, agent_cls: type[Any]) -> None:
        """Register an Agent subclass under a stable name."""
        self._entries[name] = agent_cls

    def get(self, name: str) -> type[Any] | None:
        """Get a registered Agent subclass by name."""
        return self._entries.get(name)

    def list(self) -> list[str]:
        """List all registered Agent class names."""
        return sorted(self._entries)

    def clear(self) -> None:
        """Remove all registered Agent classes."""
        self._entries.clear()


class AgentFactoryRegistry:
    """Global registry of named Agent factory callables."""

    def __init__(self) -> None:
        self._entries: dict[str, Any] = {}

    def register(self, name: str, factory: Any) -> None:
        """Register an Agent factory under a stable name."""
        self._entries[name] = factory

    def get(self, name: str) -> Any | None:
        """Get a registered Agent factory by name."""
        return self._entries.get(name)

    def list(self) -> list[str]:
        """List all registered Agent factory names."""
        return sorted(self._entries)

    def clear(self) -> None:
        """Remove all registered Agent factories."""
        self._entries.clear()


agent_class_registry = AgentClassRegistry()
agent_factory_registry = AgentFactoryRegistry()


def agent_class(name: str | None = None) -> Callable[[type[Any]], type[Any]]:
    """Decorator that registers an Agent subclass."""

    def decorator(cls: type[Any]) -> type[Any]:
        class_name = name or getattr(cls, "__name__", None)
        if not isinstance(class_name, str) or not class_name:
            raise ValueError("agent_class name must be a non-empty string")
        agent_class_registry.register(class_name, cls)
        return cls

    return decorator


def agent_factory(name: str | None = None) -> Callable[[Any], Any]:
    """Decorator that registers an Agent factory."""

    def decorator(fn: Any) -> Any:
        factory_name = name or getattr(fn, "__name__", None)
        if not isinstance(factory_name, str) or not factory_name:
            raise ValueError("agent_factory name must be a non-empty string")
        agent_factory_registry.register(factory_name, fn)
        return fn

    return decorator


__all__ = [
    "AgentClassRegistry",
    "AgentFactoryRegistry",
    "agent_class",
    "agent_class_registry",
    "agent_factory",
    "agent_factory_registry",
]
