from typing import Dict, Type, Optional
import logging
from dosuby.src.interfaces.vulnerability_checker import VulnerabilityChecker
from dosuby.src.adapter.vulnerability_checker.nvd_vulnerability_checker import NVDVulnerabilityChecker

class VulnerabilityCheckerFactory:
    """
    Factory class for creating vulnerability checker instances.
    This allows for easy switching between different vulnerability data sources.
    """
    
    # Registry of available vulnerability checker implementations
    _registry: Dict[str, Type[VulnerabilityChecker]] = {}
    
    # Default vulnerability checker
    _default_checker = "nvd"
    
    @classmethod
    def register(cls, name: str, checker_class: Type[VulnerabilityChecker]) -> None:
        """
        Register a vulnerability checker implementation.
        
        Args:
            name (str): Name of the vulnerability checker.
            checker_class (Type[VulnerabilityChecker]): The checker class.
        """
        cls._registry[name.lower()] = checker_class
    
    @classmethod
    def create(cls, name: str = None, **kwargs) -> VulnerabilityChecker:
        """
        Create a vulnerability checker instance.
        
        Args:
            name (str, optional): Name of the vulnerability checker to create.
                                  Defaults to the default checker.
            **kwargs: Additional arguments to pass to the checker constructor.
            
        Returns:
            VulnerabilityChecker: An instance of the requested vulnerability checker.
            
        Raises:
            ValueError: If the requested checker is not registered.
        """
        name = name.lower() if name else cls._default_checker
        
        if name not in cls._registry:
            logger = logging.getLogger("dosuby.vulnerability_factory")
            logger.warning(f"Vulnerability checker '{name}' not found. Using default ({cls._default_checker}).")
            name = cls._default_checker
            
        return cls._registry[name](**kwargs)
    
    @classmethod
    def set_default(cls, name: str) -> None:
        """
        Set the default vulnerability checker.
        
        Args:
            name (str): Name of the vulnerability checker to use as default.
            
        Raises:
            ValueError: If the requested checker is not registered.
        """
        if name.lower() not in cls._registry:
            raise ValueError(f"Vulnerability checker '{name}' is not registered.")
        
        cls._default_checker = name.lower()
    
    @classmethod
    def list_available(cls) -> list:
        """
        List all available vulnerability checkers.
        
        Returns:
            list: List of registered checker names.
        """
        return list(cls._registry.keys())


# Register the NVD vulnerability checker
VulnerabilityCheckerFactory.register("nvd", NVDVulnerabilityChecker)