import json,statistics,pathlib,sys
root=pathlib.Path(sys.argv[1])
data={side:json.loads((root/(side+'-20261115')/'results.json').read_text()) for side in ['base','head']}
summary={}
for side,d in data.items():
    lines=['APNs batch delivery measurement', 'Commit: '+d['sha'], 'Environment: '+d['environment'], 'One warmup excluded; 7 measured batches per scenario. Same machine and driver on both commits.', 'Times start at actual queue-consumer callback invocation. B response is fixture 200 response end; persistence is checked after batch settlement.', '']
    summary[side]={}
    for scenario in ['fast','held','held-body','in-flight']:
        rows=[r for r in d['records'] if r['scenario']==scenario]
        lines+=['Scenario: '+scenario,'run | B request ms | B 200 response ms | batch ms | request order | consumer exit']
        for r in rows:
            f=lambda x:'not sent' if x is None else f'{x:.3f}'
            lines.append(f"{r['run']} | {f(r['bRequestMs'])} | {f(r['bResponseMs'])} | {r['batchMs']:.3f} | {','.join(r['order'])} | {r['exit']}")
        metrics={}
        for name in ['bRequestMs','bResponseMs','batchMs']:
            vals=[r[name] for r in rows if r[name] is not None]
            if vals:
                metrics[name]={'median':statistics.median(vals),'min':min(vals),'max':max(vals),'spread':max(vals)-min(vals)}
                lines.append(name+': '+json.dumps(metrics[name]))
        summary[side][scenario]=metrics
        if scenario!='in-flight':
            for r in rows:
                assert r['exit']=='Success'
                assert r['order'].index('A1')<r['order'].index('A2')
                assert len(r['attempts'])==3
                assert sorted(a['apns_id'] for a in r['attempts'] if a['apns_status']==200)==(['A1','A2','B1'] if scenario=='fast' else ['A2','B1'])
                if scenario!='fast':
                    failure=next(a for a in r['attempts'] if a['apns_status'] is None)
                    assert ('read-response' if scenario=='held-body' else 'send') in failure['transport_error']
                    if side=='head': assert r['bResponseMs']<next(e['requestMs'] for e in r['events'] if e['label']=='A2')
            lines.append('Observed in every run: A1 before A2; all 3 jobs persisted; B1 and A2 status 200. '+('A1 status 200.' if scenario=='fast' else 'A1 saved as transport failure at its unchanged stage deadline.'))
        else:
            assert all(r['exit']=='Failure' for r in rows)
            assert all(('B1' in r['order'])==(side=='head') for r in rows)
            assert all('A2' not in r['order'] for r in rows)
            lines.append('A1 already claimed/in flight before invocation; A2 skipped. '+('B1 persisted 200 before batch returned failure in every run.' if side=='head' else 'B1 never sent; sequential consumer returned failure in every run.'))
        lines+=['','First measured run persisted attempt records:',json.dumps(rows[0]['attempts'],indent=2),'']
    lines+=['Exact consumer callback extracted from this commit:',(root/(side+'-20261115')/'consumer.js').read_text()]
    (root/(side+'-capture.txt')).write_text('\n'.join(lines))
for scenario in ['held','held-body']:
    b=summary['base'][scenario]['bResponseMs'];h=summary['head'][scenario]['bResponseMs']
    assert b['median']-h['median']>max(b['spread'],h['spread'])
    summary[scenario+'ImprovementMs']=b['median']-h['median']
(root/'summary.json').write_text(json.dumps(summary,indent=2))
print(json.dumps(summary,indent=2))
