from __future__ import annotations

from dataclasses import dataclass, field
from typing import Callable, Optional


@dataclass
class MiddlewareInfo:
    name: str
    description: str
    create_func: Callable[[], Any]
    metadata: dict = field(default_factory=dict)


class MiddlewareRegistry:
    _instance: Optional[MiddlewareRegistry] = None

    def __new__(cls) -> MiddlewareRegistry:
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._initialized = False
        return cls._instance

    def __init__(self):
        if self._initialized:
            return
        self._agents: dict[str, MiddlewareInfo] = {}
        self._initialized = True

    def register(
        self,
        name: str,
        description: str,
        create_func: Callable[[], Any],
        metadata: Optional[dict] = None
    ) -> None:
        self._agents[name] = MiddlewareInfo(
            name=name,
            description=description,
            create_func=create_func,
            metadata=metadata or {}
        )

    def unregister(self, name: str) -> bool:
        if name in self._agents:
            del self._agents[name]
            return True
        return False

    def get(self, name: str) -> Optional[MiddlewareInfo]:
        return self._agents.get(name)

    def list_all(self) -> list[MiddlewareInfo]:
        return list(self._agents.values())

    def get_descriptions(self) -> list[dict[str, str]]:
        return [
            {"name": agent.name, "description": agent.description}
            for agent in self._agents.values()
        ]

    def clear(self) -> None:
        self._agents.clear()


_registry: Optional[MiddlewareRegistry] = None


def get_middleware_registry() -> MiddlewareRegistry:
    global _registry
    if _registry is None:
        _registry = MiddlewareRegistry()
    return _registry
