"""Backend factory – manual registration, no file scanning."""

from __future__ import annotations

from typing import Any

from thryve.core.backends.base import BaseBackend
from thryve.core.backends.param import BaseBackendParam


class BackendFactory:
    """Create backend instances by registered name.

    Backends are registered at import time in ``core/backends/__init__.py``
    using explicit ``register()`` calls.
    """

    _backends: dict[str, tuple[type[BaseBackend], type[BaseBackendParam]]] = {}

    @classmethod
    def register(cls, name: str, backend_class: type[BaseBackend], param_class: type[BaseBackendParam]) -> None:
        """Register a backend type under *name*."""
        cls._backends[name] = (backend_class, param_class)

    @classmethod
    def create(cls, name: str, config: dict[str, Any] | BaseBackendParam) -> BaseBackend:
        """Instantiate a backend by its registered *name*."""
        if name not in cls._backends:
            available = ", ".join(sorted(cls._backends)) or "(none)"
            raise ValueError(f"Unknown backend '{name}'. Registered: {available}")

        backend_class, param_class = cls._backends[name]

        if isinstance(config, dict):
            param = param_class(**config)
        elif isinstance(config, param_class):
            param = config
        else:
            raise TypeError(
                f"Expected dict or {param_class.__name__}, got {type(config).__name__}"
            )

        return backend_class(param)

    @classmethod
    def list_backends(cls) -> list[str]:
        """Return names of all registered backends."""
        return sorted(cls._backends)
