#!/usr/bin/env python3
"""Check a published PROOFLOOP funnel file: recompute every total from its rows, and print the file's SHA-256 so
you can compare it with the hash in our post. Standard library only; imports no CAIN code.

  python3 -I verify_funnel.py https://cainstudio.online/evidence/proofloop-funnel/2026-11-07.json
  python3 -I verify_funnel.py funnel.json --sha256 <hash from the post>

Prints FUNNEL CONSISTENT when every published total equals what the rows add up to (and, with --sha256, the file is
byte-for-byte the one whose hash was published). Anything else prints FUNNEL INCONSISTENT with the difference.
"""
import argparse
import collections
import hashlib
import json
import sys
import urllib.request


def main(argv=None) -> int:
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("source", help="URL or path of the funnel JSON")
    ap.add_argument("--sha256", help="the hash published in the post")
    a = ap.parse_args(argv)
    if a.source.startswith("https://"):
        with urllib.request.urlopen(urllib.request.Request(a.source, headers={"User-Agent": "check-funnel"}),
                                    timeout=60) as r:
            raw = r.read()
    else:
        raw = open(a.source, "rb").read()
    digest = hashlib.sha256(raw).hexdigest()
    doc = json.loads(raw)
    rows, t, bad = doc["rows"], doc["totals"], []
    by = collections.Counter((r["decided_by"].split(":")[0], r["verdict"]) for r in rows)
    want = {"findings_reviewed": len(rows),
            "rejected_by_rule_filter": by[("rule_filter", "FALSE_ALARM")],
            "rejected_by_person": by[("person", "FALSE_ALARM")],
            "rejected_by_ai_reviewer": by[("ai_reviewer", "FALSE_ALARM")],
            "unsure": sum(1 for r in rows if r["verdict"] == "UNSURE"),
            "real": sum(1 for r in rows if r["verdict"] == "REAL"),
            "real_by_person": by[("person", "REAL")], "real_by_ai_reviewer": by[("ai_reviewer", "REAL")],
            "real_and_looks_like_a_buyer": sum(1 for r in rows if r["verdict"] == "REAL" and r["buyer"]),
            "by_check_among_real": dict(collections.Counter(r["check"] for r in rows if r["verdict"] == "REAL"))}
    for k, v in want.items():
        if t.get(k) != v:
            bad.append(f"{k}: published {t.get(k)}, rows add up to {v}")
    if len({r["repo_commitment"] for r in rows}) != len(rows):
        bad.append("a repository is counted more than once")
    if a.sha256 and a.sha256.lower() != digest:
        bad.append(f"file SHA-256 is {digest}, not the published {a.sha256}")
    print(f"  file sha256 {digest}")
    print(f"  {len(rows)} findings reviewed: {want['rejected_by_rule_filter']} rejected by rules, "
          f"{want['rejected_by_person']} by a person, {want['rejected_by_ai_reviewer']} by the AI reviewer, "
          f"{want['unsure']} unsure, {want['real']} real")
    for b in bad:
        print(f"  [FAIL] {b}")
    print("FUNNEL INCONSISTENT" if bad else "FUNNEL CONSISTENT")
    return 1 if bad else 0


if __name__ == "__main__":
    sys.exit(main())
