"""SGB - reporting for tracks B1..B4."""

import json
import os
import sys
from collections import defaultdict

RES = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                    "..", "results"))


def load(name):
    p = os.path.join(RES, name)
    if not os.path.exists(p):
        return []
    with open(p, encoding="utf-8") as fh:
        return [json.loads(l) for l in fh if l.strip()]


def pct(k, n):
    return "%5.1f%% (%d/%d)" % (100 * k / n if n else 0, k, n)


def b1():
    rows = load("b1_elicit.jsonl")
    if not rows:
        return
    print("=" * 92)
    print("B1 ELICIT - can the agent find what is missing and name who owns it")
    print("=" * 92)
    print("%-20s %-16s %-16s %-16s %-16s" % ("arm", "G1 gap found", "G2 field named",
                                             "G3 owner named", "G4 false alarm"))
    for arm in ("schema", "prose_deficient", "vercy_deficient"):
        sub = [r for r in rows if r["arm"] == arm]
        ng = sum(r["scored_gap"] for r in sub)
        nc = sum(r["scored_control"] for r in sub)
        print("%-20s %-16s %-16s %-16s %-16s" % (
            arm,
            pct(sum(r["gap_found"] for r in sub), ng),
            pct(sum(r["field_right"] for r in sub), ng),
            pct(sum(r["role_right"] for r in sub), ng),
            pct(sum(r["false_alarm"] for r in sub), nc)))
    print("\ncontrol questions answered correctly (no gap present)")
    for arm in ("schema", "prose_deficient", "vercy_deficient"):
        sub = [r for r in rows if r["arm"] == arm and r["scored_control"]]
        print("  %-20s %s" % (arm, pct(sum(r["control_correct"] for r in sub), len(sub))))
    print("\nper-gap detail (vercy_deficient vs prose_deficient), gap found / 2 runs")
    ids = sorted({r["task"] for r in rows if r["kind"] == "gap"})
    for t in ids:
        cells = []
        for arm in ("prose_deficient", "vercy_deficient"):
            sub = [r for r in rows if r["arm"] == arm and r["task"] == t]
            cells.append("%s %d/%d" % (arm.split("_")[0], sum(r["gap_found"] for r in sub),
                                       len(sub)))
        print("  %-9s %s" % (t, "   ".join(cells)))


def b2():
    rows = load("b2_assemble.jsonl")
    if not rows:
        return
    sel = [r for r in rows if r["stage"] == "select"]
    ans = [r for r in rows if r["stage"] == "answer"]
    print("\n" + "=" * 92)
    print("B2 ASSEMBLE - can the agent collect exactly what the question needs")
    print("=" * 92)
    n = len(sel)
    print("selection over a catalogue of 41 records")
    print("  recall of needed records      %s" % pct(sum(r["tp"] for r in sel),
                                                     sum(r["n_needed"] for r in sel)))
    print("  precision of the selection    %5.1f%%" %
          (100 * sum(r["precision"] for r in sel) / n))
    print("  records selected, mean        %.1f of 41" % (sum(r["n_selected"] for r in sel) / n))
    print("\nanswering under three assembly conditions")
    print("%-18s %-18s %-20s %-16s" % ("condition", "accuracy", "context chars", "vs full"))
    full = None
    for cond in ("full_catalogue", "self_selected", "keyword_top5"):
        sub = [r for r in ans if r["cond"] == cond]
        if not sub:
            continue
        acc = sum(r["answer_correct"] for r in sub) / len(sub)
        ctx = sum(r["context_chars"] for r in sub) / len(sub)
        if cond == "full_catalogue":
            full = ctx
        print("%-18s %-18s %-20s %-16s" % (
            cond, pct(sum(r["answer_correct"] for r in sub), len(sub)),
            "%.0f" % ctx,
            "-" if full is None or cond == "full_catalogue" else "%.0f%%" % (100 * ctx / full)))


def b3():
    rows = load("b3_exchange.jsonl")
    if not rows:
        return
    print("\n" + "=" * 92)
    print("B3 EXCHANGE - what may be disclosed to which counterparty")
    print("=" * 92)
    print("%-16s %-14s %-14s %-14s %-18s" % ("arm", "precision", "recall", "accuracy",
                                             "critical leaks"))
    for arm in ("no_policy", "prose_policy", "vercy_policy"):
        sub = [r for r in rows if r["arm"] == arm]
        tp = sum(r["tp"] for r in sub); fp = sum(r["fp"] for r in sub)
        tn = sum(r["tn"] for r in sub); fn = sum(r["fn"] for r in sub)
        leaks = sum(r["critical_leak"] for r in sub)
        tot = tp + fp + tn + fn
        print("%-16s %-14s %-14s %-14s %-18s" % (
            arm,
            "%5.1f%%" % (100 * tp / (tp + fp)) if tp + fp else "n/a",
            "%5.1f%%" % (100 * tp / (tp + fn)) if tp + fn else "n/a",
            "%5.1f%%" % (100 * (tp + tn) / tot) if tot else "n/a",
            "%d of %d decisions" % (leaks, tot)))
    print("\nby counterparty, critical leaks")
    for party in ("halden", "zen", "auditor"):
        cells = []
        for arm in ("no_policy", "prose_policy", "vercy_policy"):
            sub = [r for r in rows if r["arm"] == arm and r["party"] == party]
            cells.append("%s %d" % (arm.split("_")[0], sum(r["critical_leak"] for r in sub)))
        print("  %-9s %s" % (party, "   ".join(cells)))


def b4():
    rows = load("b4_collab.jsonl")
    if not rows:
        return
    print("\n" + "=" * 92)
    print("B4 COLLAB - two role-bound agents close a gap and record a version")
    print("=" * 92)
    print("%-20s %-14s %-14s %-16s %-14s %-14s" % (
        "arm", "C1 routing", "C2 owner", "C3 record ok", "C4 date ok", "C5 answer"))
    for arm in ("prose_deficient", "vercy_deficient"):
        sub = [r for r in rows if r["arm"] == arm]
        n = len(sub)
        print("%-20s %-14s %-14s %-16s %-14s %-14s" % (
            arm,
            pct(sum(r["route_ok"] for r in sub), n),
            pct(sum(r["owner_answered"] for r in sub), n),
            pct(sum(r["record_well_formed"] for r in sub), n),
            pct(sum(r["effective_date_right"] for r in sub), n),
            pct(sum(r["final_correct"] for r in sub), n)))
    print("\nper scenario, routing / final answer (2 runs each)")
    for t in sorted({r["task"] for r in rows}):
        cells = []
        for arm in ("prose_deficient", "vercy_deficient"):
            sub = [r for r in rows if r["arm"] == arm and r["task"] == t]
            cells.append("%s route %d/%d ans %d/%d" % (
                arm.split("_")[0], sum(r["route_ok"] for r in sub), len(sub),
                sum(r["final_correct"] for r in sub), len(sub)))
        print("  %-9s %s" % (t, "   ".join(cells)))


if __name__ == "__main__":
    b1(); b2(); b3(); b4()
