from __future__ import annotations

import threading
from collections import defaultdict
from dataclasses import dataclass
from typing import Optional, Sequence

from .settings import GatewaySettings, get_gateway_settings


@dataclass
class ProviderCredential:
    provider: str
    api_key: str
    region: Optional[str] = None
    weight: int = 1
    active: bool = True


class ProviderPool:
    """Simple round-robin credential pool per provider.

    Credentials are sourced from `GatewaySettings.providers`, which may be populated
    from configuration files or environment overrides.
    """

    def __init__(self, settings: Optional[GatewaySettings] = None) -> None:
        self._lock = threading.Lock()
        self._creds: dict[str, list[ProviderCredential]] = defaultdict(list)
        self._idx: dict[str, int] = defaultdict(int)
        resolved = settings or get_gateway_settings()
        self._load_from_settings(resolved)

    def _load_from_settings(self, settings: GatewaySettings) -> None:
        def _populate(provider: str, keys: Sequence[str]) -> None:
            for key in keys:
                trimmed = key.strip()
                if trimmed:
                    self._creds[provider].append(
                        ProviderCredential(provider=provider, api_key=trimmed)
                    )

        self._creds.clear()
        self._idx.clear()
        _populate("openai", settings.providers.openai_keys)
        _populate("anthropic", settings.providers.anthropic_keys)
        _populate("google", settings.providers.google_keys)

    def reload(self, settings: Optional[GatewaySettings] = None) -> None:
        resolved = settings or get_gateway_settings()
        with self._lock:
            self._load_from_settings(resolved)

    def acquire(self, provider: str) -> str:
        with self._lock:
            creds = [c for c in self._creds.get(provider, []) if c.active]
            if not creds:
                raise RuntimeError(f"No active credentials configured for provider '{provider}'.")
            i = self._idx[provider] % len(creds)
            self._idx[provider] += 1
            return creds[i].api_key
