import json
from pathlib import Path

def load_arm(tag):
    recs = {}
    for line in Path(f"results/parity_{tag}.jsonl").read_text().splitlines():
        if not line.strip():
            continue
        r = json.loads(line)
        kind = r["tag"]
        pid = f"{kind} {r['video']}->{r['spec_of']}"
        votes = int(str(r.get("votes", "0/3")).split("/")[0])
        passed = (r.get("verdict") == "pass")
        reason = r.get("reason", "")
        recs[pid] = dict(kind=kind, passed=passed, votes=votes, reason=str(reason))
    return recs

arms = {t: load_arm(t) for t in ("hosted", "46v", "local")}
names = {"hosted": "glm-5.3-flash", "46v": "glm-4.6v", "local": "qwen-eye"}

print(f"{'arm':16} {'pos pass':>9} {'neg block':>10} {'consist':>12}")
matrix = {}
for t, a in arms.items():
    pos = [p for p in a.values() if p["kind"] == "pos"]
    neg = [n for n in a.values() if n["kind"] == "neg"]
    pp = sum(p["passed"] for p in pos)
    nb = sum(not n["passed"] for n in neg)
    print(f"{names[t]:16} {pp:>5}/{len(pos):<3} {nb:>6}/{len(neg):<3} {pp+nb:>4}/28 ={round(100*(pp+nb)/28)}%")
    matrix[t] = dict(
        posfail=sorted(pid for pid, p in a.items() if p['kind'] == 'pos' and not p['passed']),
        negpass=sorted(pid for pid, p in a.items() if p['kind'] == 'neg' and p['passed']),
    )

print()
print("== 失败模式 ==")
for t in arms:
    m = matrix[t]
    print(f"[{names[t]}] pos误杀({len(m['posfail'])}): {', '.join(m['posfail'])}")
    print(f"[{names[t]}] neg漏放({len(m['negpass'])}): {', '.join(m['negpass'])}")

common_pos = set(matrix['hosted']['posfail'])
common_neg = set(matrix['hosted']['negpass'])
for t in ('46v', 'local'):
    common_pos &= set(matrix[t]['posfail'])
    common_neg &= set(matrix[t]['negpass'])
print("\n三臂共同误杀正样本:", ', '.join(common_pos) or "(无)")
print("三臂共同漏放负样本:", ', '.join(common_neg) or "(无)")

# local vs 08-15 历史复现性
hist = {}
for line in Path("results/judge_final_local.jsonl").read_text().splitlines():
    if not line.strip():
        continue
    r = json.loads(line)
    pid = f"{r.get('tag','?')} {r.get('video','?')}->{r.get('spec_of','?')}"
    hist[pid] = (r.get("verdict") == "pass")
lpf = sorted(matrix['local']['posfail'])
stable = [p for p in lpf if hist.get(p) is False]
flipped = [p for p in lpf if hist.get(p) is True]
unknown = [p for p in lpf if p not in hist]
print(f"\nlocal臂 pos误杀{len(lpf)}个: 与08-15一致 {len(stable)} ({', '.join(stable)})")
print(f"历史翻转 {len(flipped)} ({', '.join(flipped)}); 历史无记录 {len(unknown)}")

# 双随机臂 pairwise agreement
ids = sorted(set(arms['hosted']) & set(arms['46v']) & set(arms['local']))
agree_f4 = sum(1 for i in ids if arms['hosted'][i]['passed'] == arms['46v'][i]['passed'])
agree_fl = sum(1 for i in ids if arms['hosted'][i]['passed'] == arms['local'][i]['passed'])
agree_4l = sum(1 for i in ids if arms['46v'][i]['passed'] == arms['local'][i]['passed'])
print(f"\n两两 verdict 一致率: flash~4.6v {agree_f4}/28, flash~eye {agree_fl}/28, 4.6v~eye {agree_4l}/28")

for pid in ("neg S1-02->S2-01", "pos S3-03->S3-03", "pos S2-02->S2-02"):
    print(f"\n--- {pid} ---")
    for t in arms:
        r = arms[t].get(pid)
        if r:
            v = "PASS" if r["passed"] else "FAIL"
            print(f"  {names[t]:>14}: {v} ({r['votes']}/3) {r['reason'][:120]}")
