"""
Backend registry for embedding mode dispatch.

Backends register themselves by mode string. The registry replaces
if/elif dispatch in steganography.py with a lookup table.
"""

from __future__ import annotations

from ..exceptions import StegasooError
from .protocol import EmbeddingBackend


class BackendNotFoundError(StegasooError):
    """Raised when a requested backend mode is not registered."""


class BackendRegistry:
    """Registry mapping mode strings to embedding backends."""

    def __init__(self) -> None:
        self._backends: dict[str, EmbeddingBackend] = {}

    def register(self, backend: EmbeddingBackend) -> None:
        """Register a backend for its mode string."""
        self._backends[backend.mode] = backend

    def get(self, mode: str) -> EmbeddingBackend:
        """Look up a backend by mode. Raises BackendNotFoundError if not found."""
        if mode not in self._backends:
            available = ", ".join(sorted(self._backends.keys())) or "(none)"
            raise BackendNotFoundError(
                f"No backend registered for mode '{mode}'. Available: {available}"
            )
        return self._backends[mode]

    def has(self, mode: str) -> bool:
        """Check if a backend is registered for the given mode."""
        return mode in self._backends

    def available_modes(self, carrier_type: str | None = None) -> list[str]:
        """List registered mode strings, optionally filtered by carrier type.

        Only includes modes whose backend reports is_available() == True.
        """
        return sorted(
            mode
            for mode, backend in self._backends.items()
            if backend.is_available()
            and (carrier_type is None or backend.carrier_type == carrier_type)
        )

    def all_modes(self, carrier_type: str | None = None) -> list[str]:
        """List all registered mode strings (including unavailable ones)."""
        return sorted(
            mode
            for mode, backend in self._backends.items()
            if carrier_type is None or backend.carrier_type == carrier_type
        )


# Module-level singleton
registry = BackendRegistry()
