"""Publish an exhaustive textual before/after diff, plus compact count/prose ledgers.

The full diff includes identities, clocks, ports and gates from independent fresh DBs.
It is evidence comparison, not a claim that provider prose/event counts are deterministic.
"""
import collections
import difflib
import json
import pathlib
import sys

ROOT = pathlib.Path(__file__).resolve().parent.parent
manifest = json.loads(pathlib.Path(sys.argv[1]).read_text())
public = ROOT / "public"
ledger = {}
diffs = []
for fixture, pair in manifest.items():
    stats = {}
    for side, directory in pair.items():
        path = pathlib.Path(directory)
        states = [json.loads(p.read_text()) for p in sorted(path.glob("state-*-private.json"))]
        final = states[-1]
        nodes = collections.Counter(n["kind"] + ":" + n["status"] for n in final["nodes"])
        events = collections.Counter(e["event_type"] for e in final["events"])
        stats[side] = {
            "milestoneEventSequences": [s["eventSequence"] for s in states],
            "messageCount": len(final["messages"]),
            "nodeCountsByKindAndStatus": dict(sorted(nodes.items())),
            "eventCountsByType": dict(sorted(events.items())),
            "assistantMessages": [m["text"] for m in final["messages"] if m["role"] == "assistant"],
            "attemptStatuses": [{"runOrdinal": next(r["ordinal"] for r in final["runs"] if r["id"] == a["runId"]), "attemptOrdinal": a["attemptOrdinal"], "reason": a["reason"], "status": a["status"]} for a in final["run_attempts"]],
            "incidentalFailedTools": [{"sequence": e["sequence"], **{k: e["payload"][k] for k in ["type", "toolName", "input", "output", "status"] if k in e["payload"]}} for e in final["events"] if e["event_type"] == "turn-item.updated" and e["payload"].get("status") == "failed" and e["payload"].get("type") in {"dynamic_tool", "tool_call"}],
        }
    ledger[fixture] = stats
    before = (public / f"{fixture}-before.txt").read_text().splitlines(keepends=True)
    after = (public / f"{fixture}-after.txt").read_text().splitlines(keepends=True)
    diff = "".join(difflib.unified_diff(before, after, fromfile=f"{fixture} before ad989057ba", tofile=f"{fixture} after 827879efad"))
    (public / f"{fixture}-full-diff.txt").write_text(diff)
    diffs.append(diff)
(ROOT / "comparison-ledger-private.json").write_text(json.dumps(ledger, indent=2))
public_ledger = json.dumps(ledger, indent=2)
for value in json.loads((ROOT / "model-selections-private.json").read_text()).values():
    assert value not in public_ledger
(public / "comparison-ledger.json").write_text(public_ledger)
(public / "all-fixture-diffs.txt").write_text("\n\n".join(diffs))
for fixture, pair in ledger.items():
    print(fixture)
    for side, stats in pair.items():
        print(side, json.dumps({k: v for k, v in stats.items() if k != "eventCountsByType"}))
