"""Bounded file integrity and report export; no inference or service mutation."""
import csv
import hashlib
import json
import pathlib
import shutil

ROOT=pathlib.Path(__file__).resolve().parent.parent
PREP=ROOT.parent/'2026-10-26_contextra-camera24-prep_r01'
assets=json.loads((PREP/'reports/assets.json').read_text())
validation=json.loads((ROOT/'reports/render_validation_r02.json').read_text())
rows=json.loads((ROOT/'inputs/pose.json').read_text())

def sha(p):
    h=hashlib.sha256()
    with p.open('rb') as f:
        while b:=f.read(1024*1024):h.update(b)
    return h.hexdigest()

hashes={}
for name,asset in assets['weights'].items():
    hashes[name]=sha(PREP/asset['file'])
    assert hashes[name]==asset['sha256'],name
original=sha(PREP/'inputs/camera24_original.mp4')
assert original=='3a44966a1ce330c8fc9a0e787f859ef619ee9ac88a4fbdb3f0d26c773afc3bec'
with (ROOT/'outputs/top5_all_models.csv').open('w',encoding='utf-8-sig',newline='') as f:
    writer=csv.writer(f)
    writer.writerow(['model','source_frame','seconds','input_start','input_end','subject','status','rank','class_index','class_name','score'])
    for name in assets['weights']:
        shutil.copyfile(PREP/'reports'/('classes_'+name+'.csv'),ROOT/'outputs'/('classes_'+name+'.csv'))
        results=json.loads((ROOT/'outputs'/(name+'.json')).read_text())
        assert len(results)==201 and len({r['sample'] for r in results})==201
        for r in results:
            assert r['source_frame']==rows[r['sample']]['source_frame']
            for item in r['items']:
                subject=item.get('ids',item.get('display_id',item.get('track_id','whole_scene')))
                for rank,top in enumerate(item.get('top5',[]),1):
                    writer.writerow([name,r['source_frame'],r['seconds'],r['window']['start_seconds'],r['window']['end_seconds'],
                                     subject,item['status'],rank,top['index'],top['name'],top['score']])
        clip=ROOT/'outputs'/validation['clips'][name]['file']
        assert sha(clip)==validation['clips'][name]['sha256']
files={str(p.relative_to(ROOT)):dict(bytes=p.stat().st_size,sha256=sha(p))
       for folder in ('helpers','reports','outputs') for p in sorted((ROOT/folder).glob('*')) if p.is_file()}
manifest=dict(schema='contextra-action-eval.v1',camera_id=24,original_sha256=original,weights_sha256=hashes,
    scope='isolated recorded-video evaluation; user visual acceptance pending',files=files,
    frame_range_requested=[242,723],source_sampled_frames=[242,722],observations=201,
    test_transfer='outputs/reports only; PNG input cache retained remotely',retention='manual review; no automatic cleanup')
(ROOT/'manifest.json').write_text(json.dumps(manifest,indent=2))
print(json.dumps(dict(files=len(files),model_count=4,clips_sha256='PASS',weights_sha256='PASS',original_sha256='PASS')))
