import hashlib
import json
import os
from pathlib import Path
import resource
import statistics
import time
from collections import Counter
from review_data import verify_baseline, load_rows, Observer, bodies, Settings
from engines import Engine

clip=os.environ['CLIP']
dest=Path('/download')/clip/'data'
dest.mkdir(parents=True,exist_ok=True)
summary_path=dest/'engine_summary.json'
if summary_path.exists():
    summary=json.loads(summary_path.read_text())
    for name,digest in summary['files'].items():
        assert hashlib.sha256((dest/name).read_bytes()).hexdigest()==digest
    print('REUSED',clip)
    raise SystemExit(0)
fingerprints=verify_baseline()
rows,chosen,check,previous=load_rows(clip)
cfg=Settings();engine=Engine('B',cfg);observer=Observer(cfg)
reference_file=Path('/ab_previous')/clip/'data/B_diagnostics.jsonl'
reference=[json.loads(s) for s in reference_file.read_text().splitlines()] if reference_file.exists() else None
if reference is not None:
    assert len(reference)==len(rows)
raw_outputs=[];views=[];times=[];kinds=Counter();levels=Counter();max_groups=0
for i,row in enumerate(rows):
    prepared=bodies(row,cfg)
    before=observer.capture(engine)
    start=time.perf_counter()
    result=engine.step(row,prepared)
    times.append((time.perf_counter()-start)*1000)
    result['displayed']=row['sample'] in chosen
    if reference is not None:
        assert result==reference[i],('B_BASELINE_MISMATCH',clip,row['source_frame'])
    view=observer.explain(row,prepared,result,before)
    assert len({b['order'] for g in view['groups'] for b in view['bodies'] if b['order'] in g['orders']})==sum(len(g['orders']) for g in view['groups'])
    assert all(len(g['orders'])>=2 for g in view['groups'])
    assert all(p['input_end']==row['seconds'] and (p['input_start'] is None or p['input_start']<=row['seconds']) for p in result['pairs'])
    if result['displayed']:
        kinds.update(p['association']['kind'] for p in view['pairs'])
        levels.update(str(e['level']) for p in view['pairs'] for e in p['evidence'])
        max_groups=max(max_groups,len(view['groups']))
    raw_outputs.append(result);views.append(view)
for name,items in [('B_diagnostics.jsonl',raw_outputs),('review_diagnostics.jsonl',views)]:
    with (dest/name).open('w') as f:
        for item in items:f.write(json.dumps(item,separators=(',',':'))+'\n')
summary=dict(status='PASS',clip=clip,display_observations=len(chosen),processed_observations=len(rows),
    preceding_observations=len(rows)-len(chosen),settings=cfg.payload(),baseline_helpers=fingerprints,
    baseline_comparison='EXACT_MATCH' if reference is not None else 'NEW_INPUT_SAME_ENGINE',
    baseline_reference_sha256=hashlib.sha256(reference_file.read_bytes()).hexdigest() if reference is not None else None,
    cache_sha256=check['cache_sha256'],groups_max=max_groups,association_counts=dict(kinds),arm_levels=dict(levels),
    test_events_in_display=sum(len(r['events']) for r in raw_outputs if r['displayed']),
    current_condition_frames=sum(bool(r['current_rules']) for r in raw_outputs if r['displayed']),
    engine_p95_ms=statistics.quantiles(times,n=100,method='inclusive')[94],engine_max_ms=max(times),
    max_rss_kib=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss,
    files={name:hashlib.sha256((dest/name).read_bytes()).hexdigest() for name in ('B_diagnostics.jsonl','review_diagnostics.jsonl')})
(dest/'input_contract.json').write_text(json.dumps(dict(selected_samples=check['selected_samples'],
    cache_sha256=check['cache_sha256'],prior_rgb_hashes_sha256=hashlib.sha256((previous/'input_rgb_sha256.json').read_bytes()).hexdigest(),
    no_inference=True,no_tracking_reexecution=True,causal=True),indent=2))
summary_path.write_text(json.dumps(summary,indent=2))
print(json.dumps(summary),flush=True)
