"""Builtin command registry"""

from typing import Dict, Optional, Callable


class BuiltinCommandRegistry:
    """Singleton registry for builtin commands"""

    _instance: Optional["BuiltinCommandRegistry"] = None

    def __new__(cls) -> "BuiltinCommandRegistry":
        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._commands: Dict[str, Callable] = {}
        self._register_default_commands()
        self._initialized = True

    def _register_default_commands(self):
        """Register default builtin commands"""
        from diona.project.cli.builtin import (
            exit_command, help_command, time_command, date_command,
            list_commands_command, env_command, web_command, sub_command,
            agent_command, session_command, global_memory_command, echo_command
        )

        self.register_command("exit", exit_command)
        self.register_command("help", help_command)
        self.register_command("time", time_command)
        self.register_command("date", date_command)
        self.register_command("list-commands", list_commands_command)
        self.register_command("env", env_command)
        self.register_command("web", web_command)
        self.register_command("sub", sub_command)
        self.register_command("agent", agent_command)
        self.register_command("session", session_command)
        self.register_command("global-memory", global_memory_command)
        self.register_command("echo", echo_command)

    def register_command(self, name: str, command: Callable):
        """Register a builtin command

        Args:
            name: Command name
            command: Command implementation
        """
        self._commands[name] = command

    def unregister_command(self, name: str):
        """Unregister a builtin command

        Args:
            name: Command name
        """
        if name in self._commands:
            del self._commands[name]

    def get_command(self, name: str) -> Optional[Callable]:
        """Get a builtin command by name

        Args:
            name: Command name

        Returns:
            Command implementation or None if not found
        """
        return self._commands.get(name)

    def get_all_commands(self) -> Dict[str, Callable]:
        """Get all registered builtin commands

        Returns:
            Dictionary of command names to implementations
        """
        return self._commands.copy()

    def get_command_names(self) -> set:
        """Get all registered builtin command names

        Returns:
            Set of command names
        """
        return set(self._commands.keys())


def get_builtin_registry() -> BuiltinCommandRegistry:
    """Get the singleton builtin command registry

    Returns:
        BuiltinCommandRegistry instance
    """
    return BuiltinCommandRegistry()
