"""Hardware inspector registry and factory functions.

This module provides a centralized registry for all hardware-specific inspectors
and factory functions for convenient access.

Example:
    ```python
    from sagellm_backend.hardware.inspectors import get_inspector, list_supported_hardware

    # List all supported hardware types
    print("Supported hardware:", list_supported_hardware())

    # Get inspector for specific hardware
    cuda_inspector = get_inspector("cuda")
    profile = cuda_inspector.get_profile(include_functional=True)

    if profile.is_usable():
        print(f"CUDA available with {profile.device_count} devices")
    ```
"""

from typing import Any

from sagellm_backend.hardware.inspectors.ascend import AscendInspector
from sagellm_backend.hardware.inspectors.cpu import CPUInspector
from sagellm_backend.hardware.inspectors.cuda import CudaInspector
from sagellm_backend.hardware.inspectors.dcu import DCUInspector
from sagellm_backend.hardware.inspectors.mthreads import MThreadsInspector

# Global registry mapping hardware types to inspector classes
_INSPECTOR_REGISTRY: dict[str, type[Any]] = {
    "cuda": CudaInspector,
    "ascend": AscendInspector,
    "dcu": DCUInspector,
    "mthreads": MThreadsInspector,
    "cpu": CPUInspector,
}


def get_inspector(hardware_type: str):
    """Factory function to get hardware inspector instance.

    Args:
        hardware_type: Hardware type string ("cuda", "ascend", "cpu", etc.)

    Returns:
        Instantiated inspector for the specified hardware type

    Raises:
        ValueError: If hardware_type is not registered

    Example:
        ```python
        inspector = get_inspector("cuda")
        profile = inspector.get_profile()
        ```
    """
    if hardware_type not in _INSPECTOR_REGISTRY:
        raise ValueError(
            f"Unknown hardware type: '{hardware_type}'. "
            f"Supported types: {list_supported_hardware()}"
        )
    inspector_cls = _INSPECTOR_REGISTRY[hardware_type]
    return inspector_cls()  # type: ignore[abstract]


def list_supported_hardware() -> list[str]:
    """List all supported hardware types.

    Returns:
        List of registered hardware type strings

    Example:
        ```python
        hardware_types = list_supported_hardware()
        print(hardware_types)  # ['cuda', 'ascend', 'cpu']
        ```
    """
    return sorted(_INSPECTOR_REGISTRY.keys())


def register_inspector(hardware_type: str, inspector_class: type[Any]):
    """Register a custom hardware inspector.

    This function allows extending the framework with custom hardware support.

    Args:
        hardware_type: Hardware type identifier string
        inspector_class: Inspector class (must inherit from HardwareInspector)

    Raises:
        TypeError: If inspector_class does not inherit from HardwareInspector
        ValueError: If hardware_type is already registered

    Example:
        ```python
        from sagellm_backend.hardware.base import HardwareInspector

        class CustomGPUInspector(HardwareInspector):
            @property
            def hardware_type(self) -> str:
                return "custom_gpu"

            def inspect_l0_physical(self) -> LayerResult:
                ...

        register_inspector("custom_gpu", CustomGPUInspector)
        ```
    """
    from sagellm_backend.hardware.base import HardwareInspector

    if not issubclass(inspector_class, HardwareInspector):
        raise TypeError(
            f"Inspector class must inherit from HardwareInspector, got {inspector_class}"
        )

    if hardware_type in _INSPECTOR_REGISTRY:
        raise ValueError(
            f"Hardware type '{hardware_type}' is already registered. "
            f"Use a different name or unregister first."
        )

    _INSPECTOR_REGISTRY[hardware_type] = inspector_class


__all__ = [
    "CudaInspector",
    "AscendInspector",
    "DCUInspector",
    "MThreadsInspector",
    "CPUInspector",
    "get_inspector",
    "list_supported_hardware",
    "register_inspector",
]
