#!/usr/bin/env python3
"""Verify a Local Desk edition's evidence passport — no account, no trust.

Downloads the public passport, recomputes its seal, extracts the RFC 3161
timestamp token, and prints the receipts. Any auditor, journalist or agent
can run this against any published edition:

    python verify.py <run_id>

Exit code 0 = every check passed; 1 = do not trust the copy.
"""
import base64
import hashlib
import json
import sys
import urllib.request

BASE = "https://localdesk.news"


def canonical(value):
    """Sorted keys, compact separators, integral floats collapsed — the same
    bytes any JSON round-trip reproduces (JS parses 60.0 as 60)."""
    if value is None or not isinstance(value, (dict, list)):
        if isinstance(value, float) and value.is_integer():
            return json.dumps(int(value))
        return json.dumps(value, ensure_ascii=False)
    if isinstance(value, list):
        return "[" + ",".join(canonical(v) for v in value) + "]"
    return "{" + ",".join(
        json.dumps(k, ensure_ascii=False) + ":" + canonical(value[k]) for k in sorted(value)
    ) + "}"


def main() -> int:
    if len(sys.argv) != 2:
        print(__doc__)
        return 1
    run_id = (
        sys.argv[1].strip()
        .replace("https://localdesk.news/editions/", "")
        .replace("/passport.json", "")
        .strip("/")
    )
    url = f"{BASE}/editions/{run_id}/passport.json"
    print(f"Fetching {url} ...")
    with urllib.request.urlopen(url, timeout=30) as response:
        passport = json.loads(response.read().decode())

    shipped = passport.pop("public_passport_sha256", None)
    recomputed = hashlib.sha256(canonical(passport).encode()).hexdigest()
    ok = True

    print(f"\nEdition:          {passport.get('job_name')}")
    print(f"Verified stories: {len(passport.get('verified_stories', []))}")
    verdict = passport.get("quality_verdicts") or {}
    print(f"Quality verdict:  {'passed' if verdict.get('passed') else 'NOT PASSED'}")
    avatar = passport.get("avatar") or {}
    presenter = (
        avatar.get("presenter") or avatar.get("origin") or avatar.get("state") or "n/a"
    )
    print(f"Presenter:        {presenter}")
    head = (passport.get("audit_journal_head") or {}).get("hash")
    print(f"Audit journal:    {head}")

    print("\n1. Passport seal (recomputed over the exact bytes served):")
    if shipped and shipped == recomputed:
        print(f"   OK   {shipped}")
    else:
        ok = False
        print(f"   FAIL shipped={shipped}")
        print(f"        recomputed={recomputed}")

    ts = passport.get("timestamp") or {}
    print("\n2. Independent timestamp (RFC 3161):")
    if ts.get("token"):
        token = base64.b64decode(ts["token"])
        with open("edition-timestamp.tsr", "wb") as handle:
            handle.write(token)
        print(f"   TSA:        {ts.get('tsa')}")
        print(f"   Edition ID: {ts.get('edition_sha256')}")
        print(f"   Token:      edition-timestamp.tsr ({len(token)} bytes, DER)")
        if ts.get("identity"):
            # The imprint was computed over the exact canonical bytes; the
            # -data file must reproduce them byte for byte.
            identity = canonical(ts["identity"])
            with open("edition-identity.json", "w") as handle:
                handle.write(identity)
            print("   Identity:   edition-identity.json (canonical bytes)")
            print("   Verify offline:")
            print("     openssl ts -verify -data edition-identity.json \\")
            print("       -in edition-timestamp.tsr -CAfile tsa.crt -partial_chain")
            print("     (tsa.crt: freetsa.org's public TSA cert — freetsa.org/files/tsa.crt)")
        else:
            print("   (identity not shipped; verify with the edition's verify-kit)")
    else:
        print("   none shipped for this edition (timestamping is best-effort)")

    print(f"\n{'ALL CHECKS PASSED' if ok else 'DO NOT TRUST THIS COPY'}")
    return 0 if ok else 1


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