"""Re-verify a PresidioFlow audit snapshot's hash chain.

Evidence script for MarkHolland.tech. Verified on 2026-09-27 against
presidioflow-audit-snapshot-20260609T203143.json: 341 of 341 row hashes
recompute and every prev_hash links to the prior row_hash.

Row hash formula (reconstructed from the export, confirmed on all rows):
  sha256( utf8( json.dumps(
      {seq, record_id, batch_id, event_type, actor_type, actor_id,
       payload, prev_hash, created_at},
      sort_keys=True, separators=(",", ":"), ensure_ascii=False ) ) )

The browser lab must reproduce this exactly: recursively sorted keys,
no whitespace, non-ASCII characters left unescaped, UTF-8 bytes into
Web Crypto SHA-256. The snapshot contains no floats, so number
formatting does not differ between Python and JavaScript.

The snapshot's top-level integrity_checksum is NOT reproduced by this
script and must not be described on the site until its formula is
confirmed from the PresidioFlow source.

Usage: python verify_presidioflow_snapshot.py [snapshot.json]
"""
import hashlib
import json
import sys

FIELDS = ["seq", "record_id", "batch_id", "event_type", "actor_type",
          "actor_id", "payload", "prev_hash", "created_at"]
GENESIS = "0" * 64


def row_hash(entry: dict) -> str:
    canonical = json.dumps({k: entry[k] for k in FIELDS}, sort_keys=True,
                           separators=(",", ":"), ensure_ascii=False)
    return hashlib.sha256(canonical.encode("utf-8")).hexdigest()


def verify(path: str) -> int:
    with open(path, encoding="utf-8") as fh:
        snap = json.load(fh)
    entries = snap["ledger_entries"]
    failures = []
    prev = GENESIS
    for e in entries:
        if e["prev_hash"] != prev:
            failures.append((e["seq"], "broken link"))
        if row_hash(e) != e["row_hash"]:
            failures.append((e["seq"], "row hash mismatch"))
        prev = e["row_hash"]
    head = snap["hash_chain"]
    print(f"entries: {len(entries)}  first_hash ok: {entries[0]['row_hash'] == head['first_hash']}"
          f"  last_hash ok: {entries[-1]['row_hash'] == head['last_hash']}")
    print("CHAIN INTACT" if not failures else f"FAILURES: {failures[:10]}")
    return 0 if not failures else 1


if __name__ == "__main__":
    sys.exit(verify(sys.argv[1] if len(sys.argv) > 1
                    else "presidioflow-audit-snapshot-20260609T203143.json"))
