"""Summarize the page test: 50 pages, 3 engines, 2 runs each. Run from the folder with out/ and pages.tsv:
uv run --with beautifulsoup4 python summary.py"""
import json, statistics as S, textwrap
from analyze import load

pages = [l.split("\t")[1].strip() for l in open("pages.tsv")]
host = lambda i: pages[i - 1].split("/")[2].removeprefix("www.")
rec = lambda rc, c: sum((rc & c).values()) / max(1, sum(rc.values()))

# A page counts only when both Chrome runs got at least 50 words and no block page.
# Live pages change between loads, so the bar for "matched" is Chrome's own run-to-run match, minus 5 points, at most 0.8.
classes, scored = {"lightpanda": {}, "obscura": {}}, []
for i in range(1, 51):
    (a, ac), (b, bc) = load("r1", "chrome", i), load("r2", "chrome", i)
    if min(sum(ac.values()), sum(bc.values())) < 50 or a["blocked"] or b["blocked"]:
        continue
    scored.append(i)
    floor = min(0.8, min(rec(ac, bc), rec(bc, ac)) - 0.05)
    for e in classes:
        worst = min(max(rec(ac, c), rec(bc, c)) for c in (load(r, e, i)[1] for r in ("r1", "r2")))
        classes[e][i] = "matched" if worst >= floor else "empty" if worst < 0.1 else "partial"

print(f"pages {len(pages)}, both Chrome runs rendered {len(scored)}")
for e, d in classes.items():
    n = {k: sum(v == k for v in d.values()) for k in ("matched", "partial", "empty")}
    print(f"  {e:<10} matched {n['matched']:>2}  partial {n['partial']}  empty {n['empty']:>2}")
    for k in ("partial", "empty"):
        names = ", ".join(host(i) for i, v in d.items() if v == k)
        print(textwrap.fill(names, 84, initial_indent=f"    {k:<8} ", subsequent_indent=" " * 13))

both = [i for i in scored if classes["lightpanda"][i] == classes["obscura"][i] == "matched"]
print(f"\nsame work: the {len(both)} pages all 3 matched, 2 loads each")
print(f"  {'':<10} {'ready':>7} {'memory':>8} {'p90 mem':>8} {'snapshot':>9}")
for e in ("chrome", "lightpanda", "obscura"):
    rows = [json.load(open(f"out/{r}/{e}/{i:02d}.json")) for r in ("r1", "r2") for i in both]
    mem = sorted(x["rss_mb"] for x in rows)
    print(f"  {e:<10} {S.median(x['t_ready'] for x in rows):>6.1f}s {S.median(mem):>5.0f} MB {mem[int(.9 * len(mem))]:>5} MB"
          f" {S.median(x['snap_chars'] for x in rows):>9,.0f}")
