"""
DataSource registry for managing multiple data sources.
"""

from typing import Dict, List, Optional

from .base import DataSource
from .schema import SearchResult, SymbolInfo


class DataSourceRegistry:
    """
    Central registry for managing multiple DataSource instances.

    Allows routing symbol queries to the appropriate data source and
    aggregating search results across multiple sources.
    """

    def __init__(self):
        self._sources: Dict[str, DataSource] = {}

    def register(self, name: str, source: DataSource) -> None:
        """
        Register a data source.

        Args:
            name: Unique name for this data source
            source: DataSource implementation
        """
        self._sources[name] = source

    def unregister(self, name: str) -> None:
        """
        Unregister a data source.

        Args:
            name: Name of the data source to remove
        """
        self._sources.pop(name, None)

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

        Args:
            name: Data source name

        Returns:
            DataSource instance or None if not found
        """
        return self._sources.get(name)

    def list_sources(self) -> List[str]:
        """
        Get names of all registered data sources.

        Returns:
            List of data source names
        """
        return list(self._sources.keys())

    async def search_all(
        self,
        query: str,
        type: Optional[str] = None,
        exchange: Optional[str] = None,
        limit: int = 30,
    ) -> Dict[str, List[SearchResult]]:
        """
        Search across all registered data sources.

        Args:
            query: Search query
            type: Optional instrument type filter
            exchange: Optional exchange filter
            limit: Maximum results per source

        Returns:
            Dict mapping source name to search results
        """
        results = {}
        for name, source in self._sources.items():
            try:
                source_results = await source.search_symbols(query, type, exchange, limit)
                if source_results:
                    results[name] = source_results
            except Exception:
                # Silently skip sources that error during search
                continue
        return results

    async def resolve_symbol(self, source_name: str, symbol: str) -> SymbolInfo:
        """
        Resolve a symbol from a specific data source.

        Args:
            source_name: Name of the data source
            symbol: Symbol identifier

        Returns:
            SymbolInfo from the specified source

        Raises:
            ValueError: If source not found or symbol not found
        """
        source = self.get(source_name)
        if not source:
            raise ValueError(f"Data source '{source_name}' not found")
        return await source.resolve_symbol(symbol)
