"""Check viewer exports against benchmark definitions and stored study metrics."""
import csv, gzip, json, math, statistics
from pathlib import Path

base = Path(__file__).parent / 'paper_bench' / 'data'
manifest = json.loads((base / 'manifest.json').read_text())
cfg = json.loads((base / 'report-config.json').read_text())
rows = list(csv.DictReader((base / 'seed-metrics.csv').open()))
count = comparisons = 0
max_difference = 0.0
for scenario in manifest['scenarios']:
    for method in manifest['methods']:
        run = json.loads((base / 'runs' / scenario['id'] / (method['id'] + '.json')).read_text())
        assert len(run['cases']) == 8
        for c in run['cases']:
            assert all(len(c[k]) == len(c['tc']) for k in ['b_est', 'b_true', 'lambda', 'delta'])
            w = [i for i, t in enumerate(c['tc']) if t >= 5 and c['b_est'][i] is not None]
            e, t, a = ([c[k][i] for i in w] for k in ['b_est', 'b_true', 'lambda'])
            calc = dict(err=statistics.mean(abs(x-y) for x,y in zip(e,t)),
                        rough=1000*statistics.median(abs(e[i+2]-2*e[i+1]+e[i]) for i in range(len(e)-2)),
                        travel=sum(abs(a[i+1]-a[i]) for i in range(len(a)-1)),
                        unsafe=100*statistics.mean(x < .4-.02 for x in t))
            for key,value in calc.items():
                diff=abs(value-c['metrics'][key]); max_difference=max(max_difference,diff)
                assert diff < 1e-9, (scenario['id'],method['id'],c['id'],key,diff)
            with gzip.open(base.parent / c['signals'], 'rt') as f: signals=json.load(f)
            assert len(signals['t']) == len(signals['dc']) == len(signals['dm']) == 30720
            count += 1
        names=cfg['viewer']['studyNames'].get(method['id'],[])
        matches=[r for r in rows if r['Method'] in names and int(r['SeedOffset']) == scenario['seedOffset'] and (r['Stage']=='idle')==bool(scenario['idle'])]
        for r in matches:
            for i in range(5,9):
                assert abs(run['cases'][i-1]['metrics']['unsafe']-float(r[f'Unsafe{i}'])) < 1e-8
            err=statistics.mean(c['metrics']['err'] for c in run['cases'])
            assert abs(err-float(r['Error'])) < 1e-9
            comparisons += 1
report=dict(caseHistories=count, signalFiles=count, storedSummaryComparisons=comparisons, maxMetricDifference=max_difference)
print(json.dumps(report,indent=2))
(base.parent/'data-verification.json').write_text(json.dumps(report,indent=2)+'\n')
