"""LLM Provider 适配器模块（02-architecture-design.md §13）.

提供：
  - LLMProvider 抽象接口
  - 4 个 Provider 适配器（OpenAI / Anthropic / Baichuan / LocalOllama）
  - CircuitBreaker 熔断器
  - ProviderFailoverChain 故障切换链
  - create_failover_chain 工厂（从 Settings 构建）
"""

from typing import TYPE_CHECKING

from .base import LLMProvider, LLMResponse, LLMStreamChunk
from .circuit_breaker import CircuitBreaker, CircuitState
from .failover import ProviderFailoverChain
from .ollama_provider import LocalOllamaProvider
from .openai_provider import OpenAIProvider

if TYPE_CHECKING:
    from ..config import Settings

__all__ = [
    "LLMProvider",
    "LLMResponse",
    "LLMStreamChunk",
    "CircuitBreaker",
    "CircuitState",
    "ProviderFailoverChain",
    "OpenAIProvider",
    "AnthropicProvider",
    "BaichuanProvider",
    "LocalOllamaProvider",
    "create_failover_chain",
]


def create_failover_chain(settings: "Settings") -> ProviderFailoverChain:
    """从 Settings 构建 ProviderFailoverChain.

    按 settings.llm_provider_priority 顺序注册 Provider，
    仅注册已配置的 Provider（is_available=True）。
    """
    from .anthropic_provider import AnthropicProvider
    from .baichuan_provider import BaichuanProvider

    provider_map: dict[str, LLMProvider] = {
        "openai": OpenAIProvider(
            api_key=settings.openai_api_key,
            base_url=settings.openai_base_url,
            timeout=settings.llm_timeout_seconds,
            stream_connect_timeout=settings.llm_stream_connect_timeout,
            stream_read_timeout=settings.llm_stream_read_timeout,
        ),
        "anthropic": AnthropicProvider(
            api_key=settings.anthropic_api_key,
            base_url=settings.anthropic_base_url,
            timeout=settings.llm_timeout_seconds,
            stream_connect_timeout=settings.llm_stream_connect_timeout,
            stream_read_timeout=settings.llm_stream_read_timeout,
        ),
        "baichuan": BaichuanProvider(
            api_key=settings.baichuan_api_key,
            base_url=settings.baichuan_base_url,
            timeout=settings.llm_timeout_seconds,
            stream_connect_timeout=settings.llm_stream_connect_timeout,
            stream_read_timeout=settings.llm_stream_read_timeout,
        ),
        "local_ollama": LocalOllamaProvider(
            base_url=settings.ollama_base_url,
            timeout=settings.llm_timeout_seconds,
            stream_connect_timeout=settings.llm_stream_connect_timeout,
            stream_read_timeout=settings.llm_stream_read_timeout,
        ),
    }

    priority = settings.provider_priority_list
    providers: list[LLMProvider] = []
    for name in priority:
        provider = provider_map.get(name.strip())
        if provider is not None:
            providers.append(provider)

    # 无 Provider 时至少注册一个 OpenAI（避免构造失败）
    if not providers:
        providers.append(provider_map["openai"])

    circuit_breaker = CircuitBreaker(
        failure_threshold=3,
        cooldown_seconds=60.0,
    )
    return ProviderFailoverChain(providers, circuit_breaker)
