"""Reproduce the published aggregate analysis using Python 3, no dependencies.

Usage: python analyze_repeatability.py [path/to/repeatability-2026-09-04.csv]
Input: sanitized per-run aggregates, not raw frame samples.
"""

import csv
import math
from pathlib import Path
import statistics
import sys


def geometric(values):
    return math.exp(sum(w * math.log(v) for v, w in values) / sum(w for _, w in values))


def recalculate(row):
    gpu = geometric([(row[name + "_throughput"] / ref, 1) for name, ref in
                     [("geometry", 740), ("shader", 360), ("compute", 7600)]])
    performance = 10000 * geometric([
        (row["cpu_throughput"] / 4000, 1), (gpu, 1),
        (row["combined_throughput"] / 665, 1)])
    latency_parts = []
    for name, refs, weight in [("baseline", [2.5, 4, 6], .4), ("loaded", [9, 12, 16], .6)]:
        value = geometric([(ref / row[name + "_" + q + "_ms"], w)
                           for q, ref, w in zip(["median", "p95", "p99"], refs, [.5, .3, .2])])
        latency_parts.append((value, weight))
    latency = 10000 * geometric(latency_parts)
    consistency = 10000 * geometric([
        (ref / (row[name + "_p99_ms"] / row[name + "_median_ms"]), 1)
        for name, ref in [("cpu", 1.2), ("shader", 1.15), ("combined", 1.2),
                          ("baseline", 2.4), ("loaded", 16 / 9)]])
    pc = 10000 * geometric([(performance / 10000, .5), (latency / 10000, .3),
                            (consistency / 10000, .2)])
    return dict(pc=pc, performance=performance, core_latency=latency, consistency=consistency)


def main():
    path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).with_name("repeatability-2026-09-04.csv")
    with path.open(encoding="utf-8", newline="") as stream:
        rows = [{k: v if k in {"date", "session"} else float(v) for k, v in row.items()}
                for row in csv.DictReader(stream)]
    rows.sort(key=lambda r: r["run"])
    assert [r["run"] for r in rows] == list(range(1, 9)), "Expected the published eight runs"
    metrics = ["pc", "performance", "core_latency", "consistency"]
    error = max(abs(value - row[key]) for row in rows for key, value in recalculate(row).items())
    print(f"Maximum score reconstruction error: {error:.12g}")
    assert error < 1e-6
    for label, group in [("same boot, runs 1-3", rows[:3]),
                         ("separate boots, runs 4-6", rows[3:6]),
                         ("all 1080p, runs 1-6", rows[:6])]:
        print(label)
        for metric in metrics:
            values = [r[metric] for r in group]
            mean = statistics.mean(values)
            cv = 100 * statistics.stdev(values) / mean
            spread = 100 * (max(values) - min(values)) / mean
            print(f"  {metric}: mean={mean:.6f}; sample CV={cv:.6f}%; range/mean={spread:.6f}%")
    for row in rows[6:]:
        print(f"Resolution {row['width']:.0f}x{row['height']:.0f}")
        for metric in metrics:
            reference = statistics.mean(r[metric] for r in rows[:6])
            print(f"  {metric}: versus six-run mean={100 * (row[metric] / reference - 1):+.6f}%")
        print(f"  pc: versus run 6 in same boot={100 * (row['pc'] / rows[5]['pc'] - 1):+.6f}%")


if __name__ == "__main__":
    main()
