"""Centralized configuration using pydantic-settings.

All configuration flows through this module. Environment variables
are read at instantiation time — restart the server to pick up changes.
"""

from __future__ import annotations

import functools

from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    """Application settings loaded from environment variables.

    All Router-specific settings use the ``ROUTER_`` prefix convention.
    Provider API keys follow provider naming (``OPENAI_API_KEY``, etc).
    """

    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
    )

    # -- Authentication --
    # If set, all API endpoints (except /health) require
    # Authorization: Bearer <token> matching this value.
    # If unset or empty, auth is disabled (local dev mode).
    router_api_key: str | None = None

    # -- CORS --
    # Comma-separated list of allowed origins.
    # Empty string (default): allow localhost on any port.
    # "*": allow all origins (explicit opt-in).
    # Specific: "http://example.com,http://localhost:3000"
    router_cors_origins: str = ""

    # -- Server --
    router_port: int = 3838
    router_log_level: str = "INFO"

    # -- Rate Limiting --
    # Maximum requests per minute per client IP. 0 = disabled.
    # Default is generous (60/min) since this is a local proxy.
    router_rate_limit_per_minute: int = 60

    # -- Request Timeout --
    # Global request timeout in seconds. 0 = disabled.
    # Caps total request duration including retries and fallbacks.
    router_request_timeout_seconds: float = 120.0

    # -- Classifier --
    # Controls which provider the LLM task classifier uses.
    # "all" (default): cheapest available (gemini-2.5-flash-lite)
    # "anthropic": claude-haiku-4-5 | "openai": gpt-5.4-nano | "google": gemini-2.5-flash-lite
    router_provider_scope: str = "all"


@functools.lru_cache(maxsize=1)
def get_settings() -> Settings:
    """Return a cached Settings instance.

    Cached via ``lru_cache`` — the Settings object is created once
    and reused for all subsequent calls.  Call ``clear_settings_cache()``
    to force re-reading environment variables (used in tests).
    """
    return Settings()


def clear_settings_cache() -> None:
    """Invalidate the cached Settings object.

    After calling this, the next ``get_settings()`` call will create a
    fresh ``Settings`` instance from current environment variables.
    """
    get_settings.cache_clear()
