#!/usr/bin/env python3
"""
DFD cosmology head-to-head — one-command reproduce harness
===========================================================
Runs the install-free, load-bearing DFD-vs-LCDM scripts and checks each
headline number against its FROZEN canonical value. Honest by construction:
it reports PASS/FAIL per script and prints the corrected (theorem-checked)
status of every headline, including the items that are TIES or 1-parameter
fits rather than clean wins.

Usage:
    python3 reproduce.py            # run all headline checks
    python3 reproduce.py --quick    # skip the slowest (camb-heavy) scripts

Environment (no install step required if these are present):
    numpy, scipy, camb     (cobaya / dynesty NOT required)
"""
import subprocess, sys, time, re, importlib

HERE = __file__.rsplit("/", 1)[0] if "/" in __file__ else "."

# (script, human description, list of substrings that MUST appear in stdout to PASS)
HEADLINES = [
    ("canonical_joint_chi2.py",
     "Frozen joint chi^2 over N=2206 (CMB plik-lite + 12 BAO + Pantheon+ + lensing proxy)",
     ["DFD 1993.2", "1987.5", "593.5"],
     "slow"),
    ("lensing_chi2_native.py",
     "Native 9-bin Planck lensing chi^2 (kills the cobaya dependency); S8 resolution",
     ["chi", "DFD"],
     "slow"),
    ("laplace_evidence_v2.py",
     "Install-free Laplace evidence ln B (agnostic + SH0ES-admitted)",
     ["ln B", "B("],
     "slow"),
]

# Frozen canonical headlines (the HONEST, theorem-checked status — not overclaimed).
CANON = """
  FROZEN CANONICAL HEADLINES (honest status, 2026-06-30):
    - Joint chi^2 (N=2206):  DFD 1993.2  vs  LCDM 1987.5  =>  Delta +5.7  (statistical TIE)
    - CMB chi^2 (plik-lite): DFD 593.5  vs  LCDM 585.5    (606.0 retired as a sigma8-forcing artifact)
    - BAO (12): DFD 9.3 vs LCDM 13.2 (DFD wins);  Pantheon+ (1580): tie
    - Evidence: ΔBIC = -2.0 (marginal DFD, theta*-screen counted as 1 fitted param => DFD ~5 vs LCDM 6);
                ΔAIC = +3.7 (LCDM);  ln B = -1.9 agnostic, +9.95 with the SH0ES H0 datum admitted.
    - Derived (real wins): H0=72.09 (alpha^57 clock) -> resolves SH0ES; S8=0.783 -> resolves cosmic shear;
                           n_s=0.9667; Omega_chi h^2=0.1199; a0=2 sqrt(alpha) cH0 (MOND, DFD-only).
    - HONEST CAVEAT: the CMB acoustic-scale theta* match is a 1-PARAMETER optical screen
                     (shape/coefficient 2 sqrt(alpha) forced; amplitude gate fitted) -- DFD has
                     RELOCATED the H0 tension into one knob, not eliminated it. NOT a clean CMB kill.
"""

def have(mod):
    try: importlib.import_module(mod); return True
    except Exception: return False

def run_one(script, desc, needles, timeout=600):
    t0 = time.time()
    try:
        p = subprocess.run([sys.executable, f"{HERE}/{script}"],
                           capture_output=True, text=True, timeout=timeout)
    except subprocess.TimeoutExpired:
        return ("TIMEOUT", time.time()-t0, "")
    dt = time.time()-t0
    out = p.stdout + "\n" + p.stderr
    if p.returncode != 0:
        return ("ERROR(exit %d)" % p.returncode, dt, out)
    missing = [n for n in needles if n not in out]
    if missing:
        return ("MISMATCH(missing %r)" % missing[:2], dt, out)
    return ("PASS", dt, out)

def main():
    quick = "--quick" in sys.argv
    print("="*78)
    print(" DFD HEAD-TO-HEAD — ONE-COMMAND REPRODUCE HARNESS")
    print("="*78)
    print("\n  Environment:")
    for m in ("numpy", "scipy", "camb"):
        ok = have(m)
        v = ""
        if ok:
            try: v = importlib.import_module(m).__version__
            except Exception: v = "?"
        print(f"    {m:8s}: {'present '+v if ok else 'MISSING (required)'}")
    for m in ("cobaya", "dynesty"):
        print(f"    {m:8s}: {'present' if have(m) else 'absent (NOT required)'}")

    print(f"\n  Running {len(HEADLINES)} headline checks{' (quick: slow ones skipped)' if quick else ''}...\n")
    results = []
    for script, desc, needles, tag in HEADLINES:
        if quick and tag == "slow":
            print(f"  [skip] {script:28s} ({desc})")
            results.append((script, "SKIP", 0.0)); continue
        status, dt, out = run_one(script, desc, needles)
        mark = "OK " if status == "PASS" else "XX "
        print(f"  [{mark}] {script:28s} {status:24s} {dt:5.1f}s  {desc}")
        results.append((script, status, dt))

    npass = sum(1 for _,s,_ in results if s == "PASS")
    nrun  = sum(1 for _,s,_ in results if s not in ("SKIP",))
    print("\n" + "-"*78)
    print(f"  {npass}/{nrun} headline checks PASS")
    print(CANON)
    print("  Full verification map: README_VERIFICATION.md")
    print("="*78)
    sys.exit(0 if npass == nrun else 1)

if __name__ == "__main__":
    main()
