import datetime
import hashlib
import json
import pathlib
import sys
from collections import Counter
from control import LOCAL,REMOTE,REPORT,PREFIX,FILES,CPU_IMAGE,checked,scp,snapshot,resources,args,sync


def finish():
    after=snapshot('after');before=json.loads((REPORT/'production_before.json').read_text());changes=[]
    for key in ('config_sha256','pose_engine_sha256','pose_config_sha256','camera24'):
        if before[key]!=after[key]:changes.append(key)
    seconds=(datetime.datetime.fromisoformat(after['timestamp_utc'])-datetime.datetime.fromisoformat(before['timestamp_utc'])).total_seconds()
    rates=[]
    for sid,a in before['streams'].items():
        b=after['streams'].get(sid,{})
        for key in ('state','run_id','run_generation','child_pid','last_error','cleanup_pending'):
            if a.get(key)!=b.get(key):changes.append(sid+':'+key)
        if a['state']=='running' and a['run_id']==b.get('run_id'):
            rates.extend((name,(count-a['provider_responses'].get(name,0))/seconds) for name,count in b['provider_responses'].items())
    if set(before['streams'])!=set(after['streams']):changes.append('stream_set')
    absent=not checked(['docker','ps','-a','--filter','name='+PREFIX,'--format','{{.Names}}']).decode().strip()
    operation=dict(changes=changes,containers_unchanged=(REPORT/'containers_before.txt').read_bytes()==(REPORT/'containers_after.txt').read_bytes(),
                   state_counts=dict(Counter(s['state'] for s in after['streams'].values())),health_ready=after['health']['ready'],
                   trial_containers_absent=absent,observation_seconds=seconds,resources=resources(gpu=True),
                   provider_completion_fps=[dict(provider=n,fps=round(v,3)) for n,v in rates],
                   scope='Completion counters only; not browser FPS or realtime action acceptance.')
    (REPORT/'operational_comparison.json').write_text(json.dumps(operation,indent=2))
    for name in ('operational_comparison.json','layout_review.json','test_contract.py.txt','test_sampling.py.txt'):
        scp(str(REPORT/name),'si@58.233.207.31:'+REMOTE+'/download/validation/')
    scp(str(LOCAL/'00_README_ko.txt'),'si@58.233.207.31:'+REMOTE+'/download/')
    sync()
    _,cmd=args('render',next(iter(FILES)));name=PREFIX+'audit';cmd[cmd.index('--name')+1]=name;cmd[-1]='/helpers/audit.py'
    try:output=checked(cmd,timeout=300)
    except BaseException:
        from control import run
        run(['docker','stop','--time','15',name],timeout=40);raise
    (REPORT/'audit.log').write_bytes(output);print(output.decode(),flush=True)
    destination=LOCAL/'Contextra_PoseC3D_Nonfight_Review_20261027';destination.mkdir(exist_ok=False)
    scp('si@58.233.207.31:'+REMOTE+'/download/.',str(destination))
    hashes=json.loads((destination/'SHA256SUMS.json').read_text())
    for rel,digest in hashes.items():
        p=destination/rel
        assert not pathlib.Path(rel).is_absolute() and '..' not in pathlib.Path(rel).parts and p.is_file() and not p.is_symlink()
        assert hashlib.sha256(p.read_bytes()).hexdigest()==digest,rel
    assert len(list(destination.glob('*/*.mp4')))==8
    assert not checked(['docker','ps','-a','--filter','name='+PREFIX,'--format','{{.Names}}']).decode().strip()
    result=dict(status='PASS',inputs=4,videos=8,files=len(hashes),bytes=sum(p.stat().st_size for p in destination.rglob('*') if p.is_file()),
                destination=str(destination),operation=operation)
    (REPORT/'transfer_validation.json').write_text(json.dumps(result,indent=2));print(json.dumps(result),flush=True)


if __name__=='__main__':finish()
