"""Load config/lab.toml: model registry, run settings, paths.

The registry maps a model alias to an OpenAI-compatible endpoint. A model
with base_url "mock:" is served by the built-in mock client (used by the
smoke test so the pipeline runs without live inference). API keys are never
stored in config — `api_key_env` names an environment variable.
"""

from __future__ import annotations

import os
import tomllib
from dataclasses import dataclass, field
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parent.parent
DEFAULT_CONFIG = REPO_ROOT / "config" / "lab.toml"


@dataclass(frozen=True)
class Model:
    alias: str
    base_url: str
    model: str
    temperature: float = 0.0
    max_tokens: int = 8192
    api_key_env: str | None = None

    @property
    def is_mock(self) -> bool:
        return self.base_url.startswith("mock:")

    def api_key(self) -> str | None:
        if not self.api_key_env:
            return None
        key = os.environ.get(self.api_key_env)
        if not key:
            raise RuntimeError(
                f"model {self.alias!r} needs the {self.api_key_env} environment variable"
            )
        return key


@dataclass(frozen=True)
class RunSettings:
    samples: int = 1
    modes: tuple[str, ...] = ("oneshot", "agentic")
    max_agent_turns: int = 24
    test_timeout_secs: int = 120
    request_retries: int = 3


@dataclass(frozen=True)
class Config:
    models: dict[str, Model] = field(default_factory=dict)
    run: RunSettings = field(default_factory=RunSettings)
    raw: dict = field(default_factory=dict)


def load(path: Path | str = DEFAULT_CONFIG) -> Config:
    raw = tomllib.loads(Path(path).read_text())
    models = {}
    for alias, entry in raw.get("models", {}).items():
        if "base_url" not in entry:
            raise ValueError(
                f"[models.{alias}] has no base_url — if the alias contains a dot, "
                f'quote it: [models."{alias}"]'
            )
        models[alias] = Model(
            alias=alias,
            base_url=entry["base_url"],
            model=entry.get("model", alias),
            temperature=entry.get("temperature", 0.0),
            max_tokens=entry.get("max_tokens", 8192),
            api_key_env=entry.get("api_key_env"),
        )
    run_raw = raw.get("run", {})
    run = RunSettings(
        samples=run_raw.get("samples", 1),
        modes=tuple(run_raw.get("modes", ["oneshot", "agentic"])),
        max_agent_turns=run_raw.get("max_agent_turns", 24),
        test_timeout_secs=run_raw.get("test_timeout_secs", 120),
        request_retries=run_raw.get("request_retries", 3),
    )
    return Config(models=models, run=run, raw=raw)
