"""Validate forecast-run JSON files from a staging directory and copy them into forecasts/{study_id}/.
usage: python3 scripts/collect_forecasts.py <staging_dir>
Checks: required keys, study/agent/run match the filename, 0 <= p <= 1, low <= high,
BASELINE cites no claims, FRAMEWORK cites >= 1 claim and every cited id exists in data/claims.csv.
Nothing is edited: a run that fails is reported and left out, never repaired."""
import csv, json, os, shutil, sys
KEYS = {"study_id", "agent", "run", "p_primary_hypothesis_supported", "effect_direction",
        "effect_size_90pct_interval", "moderator_prediction", "claim_ids_used", "rationale"}
ids = {r["claim_id"] for r in csv.DictReader(open("data/claims.csv"))}
src = sys.argv[1]; ok = bad = 0
for f in sorted(os.listdir(src)):
    if not f.endswith(".json"): continue
    s, a, r = f[:-5].rsplit("_", 2)
    errs = []
    try:
        d = json.load(open(os.path.join(src, f)))
    except Exception as e:
        print(f, "UNREADABLE", e); bad += 1; continue
    if set(d) != KEYS: errs.append(f"keys {sorted(set(d) ^ KEYS)}")
    if (d.get("study_id"), d.get("agent"), str(d.get("run"))) != (s, a, r): errs.append("id/agent/run mismatch with filename")
    p = d.get("p_primary_hypothesis_supported")
    if not isinstance(p, (int, float)) or not 0 <= p <= 1: errs.append(f"p={p}")
    iv = d.get("effect_size_90pct_interval") or {}
    if not (isinstance(iv.get("low"), (int, float)) and isinstance(iv.get("high"), (int, float)) and iv["low"] <= iv["high"]): errs.append(f"interval {iv}")
    c = d.get("claim_ids_used") or []
    if a == "baseline" and c: errs.append("baseline cites claims")
    if a == "framework" and not c: errs.append("framework cites no claims")
    unknown = [x for x in c if x not in ids]
    if unknown: errs.append(f"unknown claim ids {unknown}")
    if len((d.get("rationale") or "").split()) > 130: errs.append(f"rationale {len(d['rationale'].split())} words")
    if errs:
        print(f, "FAIL", "; ".join(errs)); bad += 1; continue
    os.makedirs(f"forecasts/{s}", exist_ok=True)
    shutil.copy2(os.path.join(src, f), f"forecasts/{s}/{a}_{r}.json"); ok += 1
print(f"{ok} collected, {bad} failed")
