"""Three bounded candidate variants, using frozen features and stored baseline."""
import bootstrap
from bootstrap import SOURCE
from collections import Counter
from dataclasses import replace
import itertools
import json
from data_robust import OUT,read,paths,lines,reference
from refined import Refined,augment
from features import Settings
from state import Episode

options=[dict(id='R1',compact_hand=.12),dict(id='R2',compact_hand=.14,self_head=.08),
         dict(id='R3',compact_hand=.14,self_head=.08,mutual_hand=.18)]
cfg=read(SOURCE/'candidates.json')['candidates'][0]['config']
feedback=read(OUT/'feedback.json');results={v['id']:dict(config=v,clips={}) for v in options}
for clip in read(OUT/'specs.json'):
    fp,bp,_=paths(clip)
    engines=[Refined(cfg,v) for v in options]
    episodes=[Episode(replace(Settings(),display_hold=1.0)) for _ in options]
    stats=[dict(labels={},feedback={},new_hit_frames=[],new_negative_events=[],lost_positive_frames=[],remaining_negative_frames=[]) for _ in options]
    for row,old in itertools.zip_longest(lines(fp),lines(bp)):
        assert row is not None and old is not None
        assert all(row[k]==old[k] for k in ('sample','source_frame','seconds','displayed'))
        row=augment(row)
        tag,ids=reference(clip,old,feedback)
        for i,engine in enumerate(engines):
            r=engine.step(row);ep=episodes[i].step(row['seconds'],r['hit'],r['quiet'])
            if not row['displayed']:continue
            d=stats[i];s=d['labels'].setdefault(tag,dict(N=0,observable=0,base_hit=0,new_hit=0,base_events=0,new_events=0))
            s['N']+=1;s['observable']+=r['observable'];s['base_hit']+=old['hit'];s['new_hit']+=r['hit'];s['base_events']+=old['episode']['event'];s['new_events']+=ep['event']
            if r['hit'] and not old['hit']:d['new_hit_frames'].append(row['source_frame'])
            if tag=='positive_reference' and old['hit'] and not r['hit']:d['lost_positive_frames'].append(row['source_frame'])
            if tag=='negative_reference' and r['hit']:d['remaining_negative_frames'].append(row['source_frame'])
            if tag=='negative_reference' and ep['event'] and not old['episode']['event']:d['new_negative_events'].append(row['source_frame'])
            for key in ids:
                f=d['feedback'].setdefault(key,dict(N=0,base_hit=0,new_hit=0,base_events=0,new_events=0))
                f['N']+=1;f['base_hit']+=old['hit'];f['new_hit']+=r['hit'];f['base_events']+=old['episode']['event'];f['new_events']+=ep['event']
    for i,opt in enumerate(options):results[opt['id']]['clips'][clip]=stats[i]
    print('PROBE',clip,{v['id']:{k:(x['base_hit'],x['new_hit']) for k,x in stats[i]['labels'].items()} for i,v in enumerate(options)},flush=True)
(OUT/'reports/probe_robust.json').write_text(json.dumps(results,indent=2))
print('PROBE_COMPLETE',len(results),'variants',flush=True)
