"""Run one isolated CPU cutter, preserve originals, transfer and verify output."""
import hashlib
import json
import pathlib
import re
import shutil
import subprocess
import sys

ROOT = pathlib.Path(__file__).resolve().parent.parent
REMOTE_BASE = '/storage/contextra/experiments/action-model-eval/2026'
REMOTE_ROOT = REMOTE_BASE + '/' + ROOT.name
NAME = 'contextra-cut-user20-20261102-r01'
sys.path.insert(0,'/data/codex-artifacts/contextra/action-model-eval/2026/2026-10-27_contextra-four-scenarios-prep_r01/helpers')
import batch_job as b
import remote
TMP = pathlib.Path('/tmp/codex/ltb1021/20261102-user20-clips')
TMP.mkdir(parents=True,exist_ok=True,mode=0o700)
remote.SSH[1:1] = ['-o','ControlMaster=auto','-o','ControlPersist=60','-o','ControlPath='+str(TMP/'ssh.sock')]
SCP = ['scp'] + remote.SSH[1:-3] + ['-P',remote.SSH[-2]]
b.LOCAL=ROOT
b.SNAPSHOT_CODE=b.SNAPSHOT_CODE.replace("targets={22:'crowd',23:'loitering',26:'intrusion',29:'fire'}",'targets={}')

def command(args,sudo=False,timeout=45):
    r=remote.run(args,sudo=sudo,timeout=timeout)
    if r.returncode:
        err=re.sub(r'[a-zA-Z]+://[^\s]+','<endpoint omitted>',r.stderr.decode(errors='replace'))
        raise RuntimeError(json.dumps({'returncode':r.returncode,'stderr':err[-1500:]}))
    return r.stdout

b.command=command

def transfer(args):
    r=subprocess.run(SCP+args,capture_output=True,timeout=600)
    assert r.returncode==0,r.stderr.decode(errors='replace')[-1000:]

def digest(p):
    h=hashlib.sha256()
    with p.open('rb') as f:
        for chunk in iter(lambda:f.read(1048576),b''):h.update(chunk)
    return h.hexdigest()

def main():
    reports=ROOT/'reports';reports.mkdir()
    before=None
    try:
        b.save(reports/'safety_before.json',b.safety())
        before=b.snapshot();b.save(reports/'operational_before.json',before)
        assert command(['docker','image','inspect',b.IMAGE,'--format','{{.Id}}'],sudo=True).decode().strip()==b.IMAGE
        assert not command(['docker','ps','-aq','--filter','name=^/'+NAME+'$'],sudo=True).strip()
        uid=command(['id','-u']).decode().strip();gid=command(['id','-g']).decode().strip()
        assert uid.isdigit() and gid.isdigit() and uid!='0'
        command(['mkdir','-m','700',REMOTE_ROOT],sudo=True)
        command(['chown',uid+':'+gid,REMOTE_ROOT],sudo=True)
        command(['mkdir',REMOTE_ROOT+'/helpers',REMOTE_ROOT+'/reports'])
        transfer([str(ROOT/'manifest.json'),str(ROOT/'checkpoint.ko.md'),b.SSH[-1]+':'+REMOTE_ROOT+'/'])
        transfer([str(p) for p in (ROOT/'helpers').glob('*.py')]+[b.SSH[-1]+':'+REMOTE_ROOT+'/helpers/'])
        manifest=json.loads((ROOT/'manifest.json').read_text())
        args=['docker','run','--rm','--pull','never','--name',NAME,'--runtime','runc','--network','none','--read-only','--tmpfs','/tmp:rw,nosuid,size=128m','--cap-drop','ALL','--security-opt','no-new-privileges','--user',uid+':'+gid,'--cpus','2','--memory','2g','--pids-limit','128','-e','NVIDIA_VISIBLE_DEVICES=void','-e','PYTHONDONTWRITEBYTECODE=1','--mount',f'type=bind,src={REMOTE_ROOT},dst=/work']
        for cid,source in manifest['sources'].items():
            args += ['--mount',f'type=bind,src={REMOTE_BASE}/{source["run"]}/camera{cid}/inputs,dst=/source/camera{cid},readonly']
        args += ['--entrypoint','python3',b.IMAGE,'-B','/work/helpers/cut_worker.py']
        b.save(reports/'execution_contract.json',dict(image=b.IMAGE,container=NAME,cpus=2,memory='2GiB',network='none',readonly_root=True,user=uid+':'+gid,capabilities='ALL dropped',source_mounts_readonly=True,new_run_only_writable=True))
        print('CPU_RENDER_STARTED',flush=True)
        r=remote.run(args,sudo=True,timeout=1800)
        b.save(reports/'render_execution.json',dict(returncode=r.returncode,stdout=r.stdout.decode(errors='replace'),stderr=r.stderr.decode(errors='replace')))
        print(r.stdout.decode(errors='replace'),flush=True)
        assert r.returncode==0,r.stderr.decode(errors='replace')[-2000:]
        transfer(['-r',b.SSH[-1]+':'+REMOTE_ROOT+'/Contextra_User_Segments_20',str(ROOT)+'/'])
        transfer(['-r',b.SSH[-1]+':'+REMOTE_ROOT+'/reports',str(ROOT)+'/'])
        out=ROOT/'Contextra_User_Segments_20'
        checks=json.loads((out/'SHA256.json').read_text())
        for rel,v in checks.items():
            p=out/rel
            assert p.stat().st_size==v['bytes'] and digest(p)==v['sha256'],rel
        b.save(reports/'transfer_validation.json',dict(files=len(checks),bytes=sum(v['bytes'] for v in checks.values()),all_sizes_sha256_match=True,windows_copy_performed=False))
        print('TRANSFER_HASH_PASS '+str(len(checks)),flush=True)
    except Exception as e:
        b.save(reports/'failure.json',{'error':str(e)})
        raise
    finally:
        try:
            if command(['docker','ps','-aq','--filter','name=^/'+NAME+'$'],sudo=True).strip():
                command(['docker','stop','--time','10',NAME],sudo=True,timeout=30)
            remaining=command(['docker','ps','-aq','--filter','name=^/'+NAME+'$'],sudo=True).decode().splitlines()
            if before is not None:
                after=b.snapshot();b.save(reports/'operational_after.json',after)
                a={x['stream_id']:x for x in before['streams']};z={x['stream_id']:x for x in after['streams']}
                b.save(reports/'operational_comparison.json',dict(config_unchanged=before['config_sha256']==after['config_sha256'],containers_unchanged=before['containers']==after['containers'],channel_state_changes=[k for k in sorted(set(a)|set(z)) if a.get(k)!=z.get(k)],temporary_containers_remaining=remaining))
            b.save(reports/'safety_after.json',b.safety())
        finally:
            subprocess.run(b.SSH[:-3]+['-O','exit']+b.SSH[-3:],capture_output=True,timeout=20)

if __name__=='__main__':
    main()
