import csv
import json
from pathlib import Path
import shutil
import time
from ops import R, REPO, p

plan=p.read('plan.json')
current=p.base.inspect('contextra-analytics-1')
assert current['Id']==plan['analytics']['Id'] and current['Image']==plan['analytics']['Image']
assert current['State']['Health']['Status']=='healthy'
assert p.sha(p.ACTIVE)==plan['active_hash'] and p.sha(p.ENV)==plan['env_hash']
assert p.sha(p.prior.REG)==plan['registry_hash']
assert p.base.inspect('contextra-redis-1')['Id']==plan['redis']
assert p.prior.ops.prior.prev.sender()['executionId']==plan['sender']['executionId']
states={x['stream_id']:x for x in p.api('/api/v1/streams')['streams']}
for source,sid in p.CHANNELS.items():
    q=states[sid]
    assert q['state']=='running' and q['run_id']==plan['states'][source]['run_id']
    assert q.get('last_error') is None and q.get('cleanup_error') is None
    assert p.api('/api/v1/streams/'+sid+'/settings')['configured']==plan['settings'][source]['configured']
    assert not q['metadata_path']['performance']['detail'] and q['metadata_path']['visual'] is None
pub=p.api('/api/v1/metadata/status')['metrics']
assert pub['workers']==3 and not pub['profile']['enabled']
assert p.base.inventory()==plan['inventory']
model=Path('/data/contextra/model-artifacts/deployments/pose-batch-c869cc4-87a0ca96/RFDETRKeypointPreview')
(model/'3').mkdir(exist_ok=True)
target=model/'3/model.plan'
assert not target.exists()
shutil.copyfile(R/'pose-b4.plan',target)
assert p.sha(target)==p.read('engine.json')['sha']
acceptance={'status':'NOT_ACCEPTED_NOT_MOUNTED','reason':'batch3 selected keypoint numerical deviation',
            'probe_limit_normalized':.03,'observed_normalized':.03100600838661194,
            'limit_scope':'Batch-local diagnostic boundary, not an approved product accuracy specification',
            'engine_sha256':p.sha(target),'batch4_execution':'NOT_RUN','runtime_trial':'NOT_RUN'}
(model/'acceptance.json').write_text(json.dumps(acceptance,indent=2))
semantic=p.read('engine-semantic-check.json')
summary={'status':'RUNTIME_BLOCKED_BEFORE_MUTATION','source_tests':67,'image_tests':67,
    'engine_build':p.read('engine.json'),'semantic_probe':semantic,'acceptance':acceptance,
    'runtime_stages':[{"channels":n,"result_fps":None,"redis_fps":None,"queue":None,"drop":None,"state":"NOT_RUN"} for n in (4,8,12,16)],
    'api_start':0,'api_stop':0,'registrations':0,'recreates':0,'original_runs_preserved':True,
    'active_config_preserved':True,'sender_redis_others_preserved':True,'temporary_helpers_reaped':True,
    'pending':['Batch1/3 point deviation cause and acceptance','batch4 execution and Triton batching','image reflection and staged runtime','public decoded queue insertion'],
    'ended_at':time.time()}
p.save('summary.json',summary)
with (R/'summary.csv').open('w') as file:
    writer=csv.DictWriter(file,fieldnames=list(summary['runtime_stages'][0]));writer.writeheader();writer.writerows(summary['runtime_stages'])
p.save('final.json',dict(states=states,publisher=pub,image=current['Image'],restart=current['HostConfig']['RestartPolicy'],
    existing_runtime_unchanged=True,candidate_model=str(model),candidate_image=p.read('image.json'),summary=summary))
print(json.dumps({'state':summary['status'],'channels':{sid:states[sid]['state'] for sid in p.CHANNELS.values()},
    'workers':pub['workers'],'runtime_unchanged':True,'helper_cleanup':True}))
