# DataVow independent verifier for consentr-export-v1 (written without reading Consentr's verifier)
import json, hashlib, sys, csv
def canon(o): return json.dumps(o, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
def h(s): return hashlib.sha256(s.encode("utf-8")).hexdigest()
d = json.load(open("consentr-exemple.json", encoding="utf-8"))
ok = 0; fail = 0
def check(name, cond, extra=""):
    global ok, fail
    print(("PASS " if cond else "FAIL ") + name + (" | " + extra if extra else ""))
    if cond: ok += 1
    else: fail += 1
cc = d["consent_content"]; ag = d["agreement"]
check("canonical_json == canon(payload) (our own serialization)", canon(cc["payload"]) == cc["canonical_json"])
check("consent_hash = sha256(canon(payload))", h(canon(cc["payload"])) == ag["consent_hash"])
for p in cc["payload"]["parties"]:
    em = ag[p["role"]]["email"]
    check(f"email_sha256 {p['role']} = sha256(email)", h(em) == p["email_sha256"] or h(em.lower().strip()) == p["email_sha256"])
for side in ("party_a", "party_b"):
    check(f"signature_sha256 {side} = sha256(signature)?", any(h(x)==ev["payload"].get("signature_sha256") for ev in d["events"] if ev["party_role"]==side for x in [ag[side]["signature"]]), "rule undocumented")
prev = None
for i, ev in enumerate(d["events"]):
    check(f"event[{i}] previous_event_hash chain", ev["previous_event_hash"] == prev)
    if "payload" in ev:
        check(f"event[{i}] payload_hash", h(canon({"action": ev["action"], "payload": ev["payload"]})) == ev["payload_hash"])
    body = {"action": ev["action"], "agreement_id": ev["agreement_id"], "event_id": ev["id"],
            "occurred_at_utc": ev["occurred_at"], "party_role": ev["party_role"],
            "payload_hash": ev["payload_hash"], "previous_event_hash": ev["previous_event_hash"], "trace": ev["trace"]}
    check(f"event[{i}] event_hash (id->event_id, occurred_at->occurred_at_utc)", h(canon(body)) == ev["event_hash"])
    if "consent_hash" in ev.get("payload", {}):
        check(f"event[{i}] payload.consent_hash matches agreement", ev["payload"]["consent_hash"] == ag["consent_hash"])
    prev = ev["event_hash"]
# signed_at consistency
for ev in d["events"]:
    if ev["action"] == "signed":
        check(f"signed_at {ev['party_role']} agreement == event payload", ag[ev["party_role"]]["signed_at"] == ev["payload"]["signed_at_utc"])
# CSV vs JSON
rows = list(csv.DictReader(open("consentr-exemple.csv", encoding="utf-8")))
print("CSV columns:", list(rows[0].keys()))
check("CSV row count == events", len(rows) == len(d["events"]))
for r, ev in zip(rows, d["events"]):
    eh = r.get("event_hash"); check(f"CSV event_hash matches JSON ({ev['action']}/{ev['party_role']})", eh == ev["event_hash"])
    check("CSV consent_hash on row", r.get("consent_hash") == ag["consent_hash"])
print(f"\n{ok} pass, {fail} fail")
