"""Command manager for managing registered commands"""

import threading
from typing import Dict, Optional
from .models import CommandModel


class CommandManager:
    """Command manager singleton for managing registered commands"""
    _instance = None
    
    def __new__(cls):
        """Create a singleton instance"""
        if cls._instance is None:
            cls._instance = super(CommandManager, cls).__new__(cls)
            cls._instance._commands = {}
            cls._instance._aliases = {}
            cls._instance._lock = threading.RLock()
        return cls._instance
    
    def register_command(self, command: CommandModel):
        """Register a command
        
        Args:
            command: Command model to register
        """
        with self._lock:
            self._commands[command.name] = command
    
    def register_alias(self, alias: str, command_name: str):
        """Register an alias for a command
        
        Args:
            alias: Alias name
            command_name: Real command name
        """
        with self._lock:
            self._aliases[alias] = command_name
    
    def get_command(self, name: str) -> Optional[CommandModel]:
        """Get a registered command
        
        Args:
            name: Command name or alias
            
        Returns:
            Command model or None if not found
        """
        with self._lock:
            # Check if name is an alias
            if name in self._aliases:
                name = self._aliases[name]
            return self._commands.get(name)
    
    def hash_command(self, name: str) -> Optional[str]:
        """Get the real command name for a given name or alias
        
        Args:
            name: Command name or alias
            
        Returns:
            Real command name or None if not found
        """
        with self._lock:
            # Check if name is an alias
            if name in self._aliases:
                return self._aliases[name]
            # Check if name is a real command
            if name in self._commands:
                return name
            return None
    
    def list_commands(self) -> Dict[str, CommandModel]:
        """List all registered commands
        
        Returns:
            Dictionary of command names to command models
        """
        with self._lock:
            return self._commands.copy()
    
    def list_aliases(self) -> Dict[str, str]:
        """List all registered aliases
        
        Returns:
            Dictionary of aliases to real command names
        """
        with self._lock:
            return self._aliases.copy()
    
    def has_command(self, name: str) -> bool:
        """Check if a command is registered
        
        Args:
            name: Command name or alias
            
        Returns:
            True if command is registered, False otherwise
        """
        with self._lock:
            # Check if name is an alias
            if name in self._aliases:
                return self._aliases[name] in self._commands
            # Check if name is a real command
            return name in self._commands
