"""Canonical registry for active V5 scratch-training cases.

Canonical case IDs do not encode the training method. Historical transfer
(``_tr``) names are archive-only and are intentionally absent here.
"""
from __future__ import annotations

import argparse
from dataclasses import dataclass
from pathlib import Path
from typing import Mapping

REPO_ROOT = Path(__file__).resolve().parents[2]
TRAIN_DIR = REPO_ROOT / "src" / "drl_pinball" / "train"
CONFIG_DIR = REPO_ROOT / "configs"


@dataclass(frozen=True)
class CaseSpec:
    case_id: str
    config: str
    calibration: str
    trainer: str
    si: int
    seeds: tuple[int, ...]
    scene_type: str
    target_diam: float | None = None

    @property
    def config_path(self) -> Path:
        return CONFIG_DIR / self.config

    @property
    def calibration_path(self) -> Path:
        return TRAIN_DIR / "calibrations" / self.calibration / "calibration.json"

    @property
    def trainer_path(self) -> Path:
        return TRAIN_DIR / self.trainer

    def model_dir(self, seed: int) -> Path:
        return TRAIN_DIR / "output" / f"{self.case_id}_seed{seed}" / "models"


_CASES = (
    CaseSpec("kar_re100", "config_lbm_karman_2000x600.json", "kar_re100", "train_karman.py", 800, (41, 42, 43, 44, 45), "karman"),
    CaseSpec("kar_d075", "config_lbm_karman_2000x600.json", "kar_d075", "train_karman.py", 800, (44,), "karman"),
    CaseSpec("kar_d15", "config_lbm_karman_2000x600.json", "kar_d15", "train_karman.py", 800, (45,), "karman"),
    CaseSpec("kar_d2", "config_lbm_karman_2000x600.json", "kar_d2", "train_karman.py", 800, (45,), "karman"),
    CaseSpec("ill_075L", "config_lbm_karman_2000x600.json", "ill_075L", "train_illusion.py", 1100, (43,), "illusion", 0.75),
    CaseSpec("ill_1L", "config_lbm_karman_2000x600.json", "ill_1L", "train_illusion.py", 1200, (43,), "illusion", 1.0),
    CaseSpec("ill_15L", "config_lbm_karman_2000x600.json", "ill_15L", "train_illusion.py", 1200, (43,), "illusion", 1.5),
    CaseSpec("ill_2L", "config_lbm_karman_2000x600.json", "ill_2L", "train_illusion.py", 1200, (43,), "illusion", 2.0),
    CaseSpec("kar_re60", "config_lbm_karman_2000x600_re60.json", "kar_re60", "train_karman.py", 800, (43,), "karman"),
    CaseSpec("kar_re200", "config_lbm_karman_2000x600_re200.json", "kar_re200", "train_karman.py", 500, (43,), "karman"),
    CaseSpec("kar_re400", "config_lbm_karman_2000x600_re400.json", "kar_re400", "train_karman.py", 400, (43,), "karman"),
)

CASE_REGISTRY: Mapping[str, CaseSpec] = {case.case_id: case for case in _CASES}
CASE_IDS = tuple(CASE_REGISTRY)


def get_case(case_id: str) -> CaseSpec:
    try:
        return CASE_REGISTRY[case_id]
    except KeyError as exc:
        raise KeyError(f"Unknown canonical V5 case {case_id!r}; expected one of {CASE_IDS}") from exc


def main() -> int:
    parser = argparse.ArgumentParser(description="Query the canonical V5 case registry")
    parser.add_argument("case_id", choices=CASE_IDS)
    parser.add_argument("field", choices=("config", "calibration", "trainer", "si", "seeds", "scene_type"))
    args = parser.parse_args()
    case = get_case(args.case_id)
    values = {
        "config": case.config_path,
        "calibration": case.calibration_path,
        "trainer": case.trainer_path,
        "si": case.si,
        "seeds": ",".join(map(str, case.seeds)),
        "scene_type": case.scene_type,
    }
    print(values[args.field])
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
