from __future__ import annotations

import argparse
import re
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, Optional, Tuple


SKILLS = [
    "prime-coder.md",
    "prime-math.md",
    "prime-safety.md",
    "phuc-context.md",
    "phuc-forecast.md",
    "phuc-swarms.md",
    "phuc-cleanup.md",
]


@dataclass(frozen=True)
class ReportSpec:
    label: str
    path: Path


def _repo_root() -> Path:
    return Path(__file__).resolve().parents[3]


def _read(path: Path) -> str:
    return path.read_text(encoding="utf-8")


def parse_gpt_style_report(text: str) -> Dict[str, Tuple[int, int]]:
    out: Dict[str, Tuple[int, int]] = {}
    for skill in SKILLS:
        # Sections use headings like: "## prime-coder.md"
        m = re.search(
            rf"^##\s+{re.escape(skill)}\s*$.*?^- Score before:\s*(\d+)/10.*?^- Score after:\s*(\d+)/10",
            text,
            flags=re.M | re.S,
        )
        if not m:
            continue
        out[skill] = (int(m.group(1)), int(m.group(2)))
    return out


def parse_gemini_report(text: str) -> Dict[str, Tuple[int, int]]:
    out: Dict[str, Tuple[int, int]] = {}
    for skill in SKILLS:
        # Gemini report only scores a subset; look for section headers like:
        # "### 1. Prime Safety (`prime-safety.md`)"
        sec = re.search(
            rf"^### [^\n]*\(`{re.escape(skill)}`\)[^\n]*\n.*?(?=^### |\Z)",
            text,
            flags=re.M | re.S,
        )
        if not sec:
            continue
        scores = re.findall(r"Score:\s*(\d+)/10", sec.group(0))
        if len(scores) >= 2:
            out[skill] = (int(scores[0]), int(scores[1]))
    return out


def _fmt_pair(pair: Optional[Tuple[int, int]]) -> str:
    if not pair:
        return "n/a"
    return f"{pair[0]} → {pair[1]}"


def generate_readme(*, root: Path) -> str:
    results_dir = root / "ai-steroids-results"
    reports = [
        ReportSpec("Gemini 3 Flash", results_dir / "gemini3-flash-on-steroids.md"),
        ReportSpec("GPT-5.1 mini", results_dir / "gpt5.1-mini-on-ai-steroids.md"),
        ReportSpec("GPT-5.2", results_dir / "gpt5.2-on-ai-steroids.md"),
        ReportSpec("GPT-5.3", results_dir / "gpt5.3-on-ai-steroids.md"),
    ]

    parsed: Dict[str, Dict[str, Tuple[int, int]]] = {}
    for r in reports:
        t = _read(r.path)
        if r.label.startswith("Gemini"):
            parsed[r.label] = parse_gemini_report(t)
        else:
            parsed[r.label] = parse_gpt_style_report(t)

    lines: list[str] = []
    lines.append("# AI Steroids Results (Consolidated)\n")
    lines.append("\n")
    lines.append("> Generated by `python -m stillwater.gen_ai_steroids_readme` (or `stillwater gen-ai-steroids-readme`).\n")
    lines.append("\n")
    lines.append("This folder contains human-readable score reports for “model on Stillwater skills” evaluations.\n")
    lines.append("\n")
    lines.append("Two different things are mixed in these reports:\n")
    lines.append("1) **Spec-based scoring** (reading `skills/*.md` and rating expected discipline/auditability uplift)\n")
    lines.append("2) **Receipt-based benchmarking** (running the deterministic A/B harness that emits artifacts under `artifacts/skills_ab/`)\n")
    lines.append("\n")
    lines.append("If you want replayable evidence, use the harness (`python -m stillwater.skills_ab`).\n")
    lines.append("\n")
    lines.append("## Files\n\n")
    for r in reports:
        lines.append(f"- `{r.path.name}`\n")

    lines.append("\n## Rubric (shared)\n\n")
    lines.append("All the `gpt5.*` reports use a similar rubric: **1–10** scoring for how well each skill pushes the model toward:\n")
    lines.append("- determinism (repeatable process)\n")
    lines.append("- evidence/receipts (Red→Green gates; “no green without proof”)\n")
    lines.append("- bounded scope + stop rules\n")
    lines.append("- auditability (why actions happened)\n")
    lines.append("- safe tool use + fail-closed refusal/NEED_INFO\n")

    lines.append("\n## Consolidated scores (by skill)\n\n")
    lines.append("These are the “before → after” numbers as reported in each file (not re-measured here).\n\n")

    headers = ["Skill"] + [r.label for r in reports]
    lines.append("| " + " | ".join(headers) + " |\n")
    lines.append("|" + "|".join(["---"] + [":---:" for _ in reports]) + "|\n")
    for skill in SKILLS:
        row = [f"`{skill}`"]
        for r in reports:
            row.append(_fmt_pair(parsed.get(r.label, {}).get(skill)))
        lines.append("| " + " | ".join(row) + " |\n")

    lines.append("\nNotes:\n")
    lines.append("- The Gemini report only assigns explicit “Score: X/10” for a subset of skills; missing entries are `n/a`.\n")
    lines.append("- `gpt5.3-on-ai-steroids.md` is explicitly spec-based expectation scoring (not a receipt-backed run).\n")

    lines.append("\n## What’s actually reproducible (receipts)\n\n")
    lines.append("The repo’s receipts generator for these move-cards is the skills A/B harness:\n\n")
    lines.append("```bash\n")
    lines.append("PYTHONPATH=cli/src STILLWATER_AB_BACKEND=mock STILLWATER_AB_CACHE=0 \\\n")
    lines.append("  python -m stillwater.skills_ab\n")
    lines.append("```\n\n")
    lines.append("Outputs:\n")
    lines.append("- `artifacts/skills_ab/results.json` (machine-readable)\n")
    lines.append("- `artifacts/skills_ab/report.md` (human-readable)\n\n")
    lines.append("The notebook `PHUC-SKILLS-SECRET-SAUCE.ipynb` is a thin UI wrapper over the same harness.\n")

    return "".join(lines)


def main(argv: list[str] | None = None) -> int:
    p = argparse.ArgumentParser(description="Generate ai-steroids-results/README.md from the per-model reports.")
    p.add_argument("--check", action="store_true", help="Exit non-zero if README would change.")
    ns = p.parse_args(argv)

    root = _repo_root()
    out_path = root / "ai-steroids-results" / "README.md"
    new_text = generate_readme(root=root)

    if ns.check and out_path.exists():
        old = _read(out_path)
        if old != new_text:
            print(f"README out of date: {out_path}")
            return 1
        return 0

    out_path.parent.mkdir(parents=True, exist_ok=True)
    out_path.write_text(new_text, encoding="utf-8")
    return 0


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