#!/usr/bin/env python3
"""Agent Arena fingerprint checker. Python 3, standard library only. Paper trading only.
Usage:  python3 verify.py                      # checks the live site, latest day
        python3 verify.py --date 2026-10-13    # a specific day
        python3 verify.py --dir ./site         # a local copy of the site files instead of the web
It recomputes every bot's ledger fingerprint, the daily root, the link to the previous day,
every order receipt, and checks each published trade log matches the fingerprinted ledger."""
import json, hashlib, sys, argparse, urllib.request, os
ap = argparse.ArgumentParser(); ap.add_argument("--base", default="https://agentarenaleague.pages.dev"); ap.add_argument("--dir"); ap.add_argument("--date"); ap.add_argument("--bot")
A = ap.parse_args()
def get(path):
    if A.dir: return json.load(open(os.path.join(A.dir, path.lstrip("/")), encoding="utf-8"))
    return json.load(urllib.request.urlopen(urllib.request.Request(A.base.rstrip("/") + path, headers={"user-agent": "arena-verify"}), timeout=60))
from decimal import Decimal, ROUND_HALF_UP, localcontext
def fixw(v):
    """Canonical weight string: fixed 10 decimals, round half up on the exact binary value (same as JavaScript toFixed(10))."""
    v = float(v); v = 0.0 if v == 0 else v
    with localcontext() as c:
        c.prec = 400
        return format(Decimal(v).quantize(Decimal("1e-10"), rounding=ROUND_HALF_UP), "f")
canon = lambda o: json.dumps(o, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
H = lambda o: hashlib.sha256(canon(o).encode()).hexdigest()
B = get(f"/data/fingerprints/{A.date or 'latest'}.json"); bad = 0
print("Day", B["date"], "| bots", len(B["bots"]), "| published root", B["root"])
root = H({"date": B["date"], "prev_root": B["prev_root"], "bots": B["bots"]})
print(("OK  " if root == B["root"] else "FAIL") + " daily root recomputed"); bad += root != B["root"]
P = get(f"/data/fingerprints/{B['prev_date']}.json") if B.get("prev_date") else None
if P: ok = P["root"] == B["prev_root"]; bad += not ok; print(("OK  " if ok else "FAIL") + f" chain link to {P['date']}")
for i, h in sorted(B["bots"].items()):
    if A.bot and i != A.bot: continue
    L = get(f"/data/ledger/{i}.json"); errs = []
    if A.date is None or L["date"] == B["date"]:
        if H({"bot": i, "date": B["date"], "prev": L["prev"], "doc": L["doc"]}) != h: errs.append("ledger fingerprint mismatch")
        if P and L["prev"] != P["bots"].get(i): errs.append("prev link mismatch")
        if A.date is None:
            t = get(f"/data/trades/{i}.json")
            if t["fills"] != L["doc"]["fills"]: errs.append("trade log differs from fingerprinted ledger")
    for r in L["doc"].get("receipts", []):
        w = {k: (v if isinstance(v, str) else fixw(v)) for k, v in r["weights"].items()}
        if any(v != fixw(v) for v in w.values()) or H({"agent_id": r["agent_id"], "date": r["date"], "received_at": r["received_at"], "weights": w}) != r["sha256"]: errs.append(f"order receipt #{r['seq']} mismatch")
    bad += bool(errs)
    if errs or A.bot: print(("FAIL " + "; ".join(errs) if errs else "OK  ") + " " + i)
print("ALL CHECKS PASSED" if not bad else f"{bad} CHECK(S) FAILED"); sys.exit(1 if bad else 0)
