from ops import *
import statistics

trial=json.loads((HERE/'trial-result.json').read_text())
samples=[json.loads(line) for line in (HERE/'samples.jsonl').read_text().splitlines()]
first,last=samples[0],samples[-1]
seconds=last['t']-first['t']
rows=[]
for camera,r in last['channels'].items():
    for provider,v in r['providers'].items():
        before=first['channels'][camera]['providers'][provider]
        a,b=before['metadata_path'],v['metadata_path']
        ap,bp=before['publisher_metrics'],v['publisher_metrics']
        rows.append(dict(camera=int(camera),provider=provider,
            completed_fps=(b['providers'][provider]['responses']-a['providers'][provider]['responses'])/seconds,
            redis_fps=(bp.get('sent_frames',0)-ap.get('sent_frames',0))/seconds,
            counters={k:b.get(k,0)-a.get(k,0)
                      for k in ('finalized','completed_queue_expired','completed_queue_drop')},
            sender={k:bp.get(k,0)-ap.get(k,0) for k in ('replaced','expired','send_error')},
            crowd=b.get('crowd'), artifact=b.get('artifacts'),
            timing=b.get('performance',{})))
redis=json.loads((HERE/'redis-observation.json').read_text())
observed=[]
for camera in (3,8):
    for provider in ('pose','fire','crowd'):
        points=[r for r in redis['rows'] if str(r['camera'])==str(camera) and r['provider']==provider]
        assert points and all(p['required']==['pose','fire','crowd'] for p in points)
        assert all(b['seq']>a['seq'] and b['pts']>a['pts'] for a,b in zip(points,points[1:]))
        if provider=='crowd':
            assert all('regions' in (p['crowd'] or {}) for p in points)
        else:
            assert all(p['crowd'] is None for p in points)
        observed.append(dict(camera=camera,provider=provider,messages=len(points),fps=len(points)/redis['seconds'],
            max_gap_s=max((b['elapsed']-a['elapsed'] for a,b in zip(points,points[1:])),default=0),
            empty_visible=sum(not p['visible'] for p in points),
            statuses=sorted({r['status'] for p in points for r in (p['crowd'] or {}).get('regions',[])})))
def cpu(s):return list(map(int,s.split()[1:]))[:8]
a,b=cpu(first['resources']['host_cpu']),cpu(last['resources']['host_cpu'])
delta=[y-x for x,y in zip(a,b)]
cpu_percent=100*(sum(delta)-delta[3]-delta[4])/sum(delta)
summary=dict(seconds=seconds,rows=rows,redis_observed=observed,cpu_mean_percent=cpu_percent,
    gpu_mean_percent=statistics.mean(float(s['gpu'].split(',')[0]) for s in samples),
    renderer_max_sampled=max(s['artifacts'].get('rendering',0) for s in samples),
    cleanup=trial['cleanup']['reaped'],errors=trial['errors'])
save('summary-v2.json',summary)
print(json.dumps({k:v for k,v in summary.items() if k!='rows'},ensure_ascii=False))
print(json.dumps([{k:v for k,v in r.items() if k not in ('timing','crowd','artifact')} for r in rows]))
