from __future__ import annotations

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


@dataclass
class ToolInfo:
    name: str
    description: str
    tool: Any
    metadata: dict = field(default_factory=dict)


class ToolRegistry:
    _instance: Optional[ToolRegistry] = None

    def __new__(cls) -> ToolRegistry:
        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._tools: dict[str, ToolInfo] = {}
        self._initialized = True

    def register(
        self,
        name: str,
        description: str,
        tool: Any,
        metadata: Optional[dict] = None
    ) -> None:
        self._tools[name] = ToolInfo(
            name=name,
            description=description,
            tool=tool,
            metadata=metadata or {}
        )

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

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

    def list_all(self) -> list[ToolInfo]:
        return list(self._tools.values())

    def get_tools(self) -> list[Any]:
        return [info.tool for info in self._tools.values()]

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


_registry: Optional[ToolRegistry] = None


def get_tool_registry() -> ToolRegistry:
    global _registry
    if _registry is None:
        _registry = ToolRegistry()
    return _registry
