import csv
import importlib.util
import json
from pathlib import Path
import yaml

R=Path(__file__).parent
s=importlib.util.spec_from_file_location('ops',R/'ops.py');o=importlib.util.module_from_spec(s);s.loader.exec_module(o);p=o.p
plan=p.read('plan.json');build=p.read('off-build.json');data=p.read('single-off.json')
src='rtsp-test-source-02';sid=o.TARGET
states={s:p.prior.state(i) for s,i in p.CHANNELS.items()}
assert states[src]['state']=='running' and all(q['state']=='stopped' for s,q in states.items() if s!=src)
assert not states[src]['metadata_path']['performance']['detail'] and states[src]['metadata_path']['visual'] is None
settings={s:p.api('/api/v1/streams/'+i+'/settings') for s,i in p.CHANNELS.items()}
for s,view in settings.items():
    old=plan['settings'][s]['configured'];new=view['configured']
    for k,v in old.items():
        if s==src and k in ('revision','intrusion'):continue
        assert new[k]==v,(s,k)
    if s==src:
        assert new['tracking']['enabled'] is False and new['intrusion']['enabled'] is False
        assert all(new['intrusion'][k]==v for k,v in old['intrusion'].items() if k!='enabled')
        assert view['effective']['tracking']['enabled'] is False and not view['restart_pending']
    else:assert new['tracking']['enabled'] is True
cur=p.base.inspect('contextra-analytics-1')
assert cur['Image']==build['image'] and cur['State']['Health']['Status']=='healthy'
assert dict(x.split('=',1) for x in cur['Config']['Env'])==dict(x.split('=',1) for x in plan['analytics']['Config']['Env'])
assert sorted(cur['Mounts'],key=lambda x:x['Destination'])==sorted(plan['analytics']['Mounts'],key=lambda x:x['Destination'])
assert cur['HostConfig']['RestartPolicy']==plan['analytics']['HostConfig']['RestartPolicy']
assert p.base.inspect('contextra-redis-1')['Id']==plan['redis']
sender=p.prior.ops.prior.prev.sender();assert sender['executionId']==plan['sender']['executionId']
inventory=p.base.inventory()
assert {k:v for k,v in inventory.items() if k!='/contextra-analytics-1'}=={k:v for k,v in plan['inventory'].items() if k!='/contextra-analytics-1'}
assert yaml.safe_load(p.ACTIVE.read_text())['services']['analytics']['image']==build['image']
assert 'CONTEXTRA_IMAGE='+build['tag'] in p.ENV.read_text().splitlines()
preset=yaml.safe_load(Path(plan['preset']).read_text())
assert preset['settings']['tracking']['enabled'] is False and preset['settings']['intrusion']['enabled'] is False
before=yaml.safe_load((R/'registry.before').read_text());after=yaml.safe_load(p.prior.REG.read_text())
for row in before['added']:
    match=next(x for x in after['added'] if x['stream_id']==row['stream_id'])
    if row['stream_id']!=sid:assert match==row
    else:
        assert all(match[k]==v for k,v in row.items() if k not in ('intrusion','tracking'))
        assert match['tracking']['enabled'] is False and match['intrusion']['enabled'] is False
frames=[x['channels'][src]['redis']['frame'] for x in data['samples']]
assert len({f['runId'] for f in frames})==1
assert all(f['sourceId']==src and f['frameTime']['rtpClockRate']==90000 and f['frameTime']['rtpTimestamp'] is not None for f in frames)
assert all(obj['trackId'] is None for f in frames for obj in f['objects'])
assert all(not f.get('events') and not f.get('scenarioConfig') for f in frames)
assert all(not x['channels'][src]['state']['scenarios']['active'] for x in data['samples'])
assert all(not x['channels'][src]['state']['metadata_path']['performance']['tracking_profiles'] for x in data['samples'])
summary=p.read('single-off-summary.json')[src]
assert summary['counter_delta'].get('stale',0)==0 and summary['counter_delta'].get('queue_drop',0)==0
assert summary['fps']['result']>=9.5 and summary['redis_fps']>=9.5
a,b=data['resources'];dt=b['at']-a['at']
resources=dict(cpu_cores=(b['cpu']['usage_usec']-a['cpu']['usage_usec'])/1e6/dt,memory_mib=[a['memory']/1024**2,b['memory']/1024**2],gpu=[a['gpu'],b['gpu']])
row=dict(channel='02',seconds=summary['seconds'],**{k+'_fps':v for k,v in summary['fps'].items()},redis_fps=summary['redis_fps'],queue_min=min(summary['queue']),queue_max=max(summary['queue']),stale_delta=summary['counter_delta'].get('stale',0),capacity_drop_delta=summary['counter_delta'].get('queue_drop',0))
with (R/'comparison.csv').open('w') as f:
    writer=csv.DictWriter(f,fieldnames=list(row));writer.writeheader();writer.writerow(row)
p.save('final.json',dict(row=row,resources=resources,states=states,settings=settings,image=build['image'],tag=build['tag'],
    sender_preserved=True,redis_preserved=True,non_target_registrations_preserved=True,env_mount_restart_preserved=True,
    frames_checked=len(frames),null_track_ids=True,intrusion_off=True,metrics_off=True,
    publisher_queue_max=max(x['publisher']['metrics']['queued'] for x in data['samples']),
    preset=p.read('plan.json')['preset']))
print(json.dumps(dict(row=row,states={s:q['state'] for s,q in states.items()},resources=resources,frames=len(frames))))
