"""Adapter registry with safe generic fallback."""

from __future__ import annotations

import logging
from collections.abc import Iterable

from app.adapters.base import SiteAdapter
from app.adapters.generic_html import GenericHTMLAdapter
from app.adapters.luticlip import LutiClipAdapter

logger = logging.getLogger(__name__)


class AdapterRegistry:
    def __init__(
        self,
        site_adapters: Iterable[SiteAdapter] | None = None,
        generic: SiteAdapter | None = None,
    ) -> None:
        self.generic = generic or GenericHTMLAdapter()
        self.site_adapters = list(site_adapters or [])
        names = [adapter.name for adapter in self.site_adapters]
        if len(names) != len(set(names)):
            raise ValueError("adapter names must be unique")
        if any(adapter.name == self.generic.name for adapter in self.site_adapters):
            raise ValueError("generic adapter name is reserved")

    @property
    def all_adapters(self) -> list[SiteAdapter]:
        return [*self.site_adapters, self.generic]

    def resolve(self, url: str) -> SiteAdapter:
        for adapter in self.site_adapters:
            try:
                if adapter.supports(url):
                    return adapter
            except Exception:  # noqa: BLE001 - a broken adapter must not block fallback
                logger.exception("adapter %s supports() failed", adapter.name)
        return self.generic

    def register(self, adapter: SiteAdapter) -> None:
        if any(existing.name == adapter.name for existing in self.all_adapters):
            raise ValueError(f"adapter already registered: {adapter.name}")
        self.site_adapters.insert(0, adapter)


def build_default_registry() -> AdapterRegistry:
    """Register project-specific adapters here.

    Example:
        from my_site import MySiteAdapter
        return AdapterRegistry(site_adapters=[MySiteAdapter()])
    """

    return AdapterRegistry(site_adapters=[LutiClipAdapter()])
