"""
Provider Registry - Singleton pattern for managing translation providers.

Provides a central registry for all translation providers with:
- Registration and retrieval by name
- Listing available providers
- Fallback chain support
"""

from typing import Dict, List, Optional
import threading

from .base import TranslationProvider


class ProviderRegistry:
    """
    Singleton registry for translation providers.

    Thread-safe implementation for managing multiple translation providers
    with support for fallback chains.
    """

    _instance: Optional["ProviderRegistry"] = None
    _lock: threading.Lock = threading.Lock()

    def __new__(cls) -> "ProviderRegistry":
        """Create or return the singleton instance."""
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
                    cls._instance._providers: Dict[str, TranslationProvider] = {}
                    cls._instance._providers_lock = threading.RLock()
        return cls._instance

    def register(self, name: str, provider: TranslationProvider) -> None:
        """
        Register a translation provider.

        Args:
            name: Unique name for the provider (e.g., "google", "openai")
            provider: TranslationProvider instance
        """
        with self._providers_lock:
            self._providers[name] = provider

    def unregister(self, name: str) -> bool:
        """
        Unregister a translation provider.

        Args:
            name: Name of the provider to remove

        Returns:
            True if provider was removed, False if not found
        """
        with self._providers_lock:
            if name in self._providers:
                del self._providers[name]
                return True
            return False

    def get(self, name: str) -> Optional[TranslationProvider]:
        """
        Get a registered provider by name.

        Args:
            name: Provider name

        Returns:
            TranslationProvider instance or None if not found
        """
        with self._providers_lock:
            return self._providers.get(name)

    def list_all(self) -> List[str]:
        """
        List all registered provider names.

        Returns:
            List of provider names
        """
        with self._providers_lock:
            return list(self._providers.keys())

    def list_available(self) -> List[str]:
        """
        List names of all available (reachable) providers.

        Returns:
            List of provider names that are currently available
        """
        with self._providers_lock:
            return [
                name
                for name, provider in self._providers.items()
                if provider.is_available()
            ]

    def get_first_available(self, names: List[str]) -> Optional[TranslationProvider]:
        """
        Get the first available provider from a list of names (fallback chain).

        Iterates through the list in order and returns the first provider
        that is available. This enables graceful degradation when providers
        are unavailable.

        Args:
            names: List of provider names in priority order

        Returns:
            First available TranslationProvider or None if all are unavailable
        """
        for name in names:
            provider = self.get(name)
            if provider is not None and provider.is_available():
                return provider
        return None

    def clear(self) -> None:
        """Remove all registered providers."""
        with self._providers_lock:
            self._providers.clear()

    def __len__(self) -> int:
        """Return the number of registered providers."""
        with self._providers_lock:
            return len(self._providers)

    def __contains__(self, name: str) -> bool:
        """Check if a provider is registered."""
        with self._providers_lock:
            return name in self._providers


def get_registry() -> ProviderRegistry:
    """
    Get the global provider registry instance.

    Returns:
        The singleton ProviderRegistry instance
    """
    return ProviderRegistry()


# Global registry instance
registry = ProviderRegistry()
