from __future__ import annotations
import hashlib, json
from pathlib import Path

ROOT = Path(__file__).resolve().parents[2]
HERE = Path(__file__).resolve().parent
EXPECTED_PROTECTED = {
    "main.tex": "fd4fe7cf9a0d42e9a9a1def50d49c4a03d8fcd6772f857cc5a269e183986e34a",
    "main.pdf": "77b1fd720821e0398337a6a7fceed570dc50093534fe9b60795a1524e4a0cf54",
}
EXPECTED_BOARD = "FROG_8_OF_8_GREEN_AT_RESEARCH_DERIVATION_LEVEL"
EXPECTED_GLOBAL = "PASS_ONE_QCD_GENERATING_FUNCTIONAL__VACUUM_AND_NUCLEON_EM_RESPONSES__NO_HADRONIC_FIT_COEFFICIENTS"

def sha256(path: Path) -> str:
    h=hashlib.sha256()
    with path.open("rb") as f:
        for block in iter(lambda:f.read(1024*1024), b""):
            h.update(block)
    return h.hexdigest()

def main() -> int:
    checks = {}
    for name, expected in EXPECTED_PROTECTED.items():
        p=ROOT/name
        checks[f"protected_{name}_exists"] = p.exists()
        checks[f"protected_{name}_hash"] = p.exists() and sha256(p)==expected

    status_path=HERE/"FROG_STATUS_2026-08-19.json"
    master_path=HERE/"UTFANSWF_FROG_8_OF_8_GREEN_GLOBAL_NPQCD_CLOSEOUT_2026-08-19.md"
    manifest_path=HERE/"FROG_SOURCE_MANIFEST.json"
    checks["status_exists"] = status_path.exists()
    checks["master_exists"] = master_path.exists()
    checks["manifest_exists"] = manifest_path.exists()

    status=json.loads(status_path.read_text(encoding="utf-8")) if status_path.exists() else {}
    checks["board_verdict"] = status.get("board_verdict")==EXPECTED_BOARD
    checks["global_npqcd_verdict"] = status.get("global_npqcd_verdict")==EXPECTED_GLOBAL
    items=status.get("items",[])
    checks["eight_items_present"] = len(items)==8 and [x.get("id") for x in items]==list(range(1,9))
    checks["eight_items_green"] = len(items)==8 and all(x.get("status")=="GREEN" for x in items)
    not_claimed=" ".join(status.get("not_claimed",[])).lower()
    checks["numerical_execution_not_overclaimed"] = "production-scale numerical" in not_claimed
    checks["independent_verification_not_overclaimed"] = "independent third-party verification" in not_claimed
    checks["historical_rows_not_rewritten"] = "historical row 27" in not_claimed and "row 29" in not_claimed

    if master_path.exists():
        text=master_path.read_text(encoding="utf-8")
        checks["master_contains_npqcd_verdict"] = EXPECTED_GLOBAL in text
        checks["master_contains_8of8"] = "FROG }8/8" in text or "FROG 8/8" in text
        checks["master_preserves_pending_execution"] = "numerical NP-QCD execution" in text and "independent verification pending" in text
    else:
        checks["master_contains_npqcd_verdict"] = False
        checks["master_contains_8of8"] = False
        checks["master_preserves_pending_execution"] = False

    manifest=json.loads(manifest_path.read_text(encoding="utf-8")) if manifest_path.exists() else {}
    bad=[]
    for rec in manifest.get("files",[]):
        p=HERE/rec["path"]
        if not p.exists() or sha256(p)!=rec["sha256"]:
            bad.append(rec["path"])
    checks["source_manifest_hashes"] = bool(manifest.get("files")) and not bad

    verdict="PASS" if all(checks.values()) else "FAIL"
    out={
        "gate":"frog_8_of_8_research_overlay_integrity",
        "context":"POST_RELEASE_RESEARCH",
        "tier":"Auxiliary integrity",
        "blocking":True,
        "verdict":verdict,
        "status":EXPECTED_BOARD if verdict=="PASS" else "FROG_OVERLAY_INTEGRITY_FAIL",
        "checks":checks,
        "bad_manifest_files":bad,
        "protected_hashes":EXPECTED_PROTECTED,
        "claim_boundary":"Research-derivation closeout only; numerical NP-QCD execution and independent verification remain pending."
    }
    result_dir=ROOT/"results"/"frog_closeout"
    result_dir.mkdir(parents=True, exist_ok=True)
    (result_dir/"result.json").write_text(json.dumps(out,indent=2,sort_keys=True)+"\n",encoding="utf-8")
    print(json.dumps(out,indent=2,sort_keys=True))
    return 0 if verdict=="PASS" else 1

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