import pathlib, subprocess, json, hashlib, shutil, os, sys
import yaml
sys.path.insert(0, '/workspace/contextra-analytics-runtime-lifecycle-refactor')
from tools.validate_deployment import load_env_file, validate_deployment_inputs

os.umask(0o077)
R = pathlib.Path(__file__).parent
REPO = pathlib.Path('/workspace/contextra-analytics-runtime-lifecycle-refactor')
ENV = pathlib.Path('/workspace/contextra-runtime-config/runtime.env')
CFG = pathlib.Path('/data/contextra/models/triton/RFDETRMedium/config.pbtxt')
TAG = 'contextra-analytics:det-window-99698a0'
HEAD = '99698a072a014b7cca4300c37c3dd5a3f1982090'
def sha(p): return hashlib.sha256(p.read_bytes()).hexdigest()
def shell(args): return subprocess.check_output(args, text=True, timeout=20)
def inspect_all():
    ids = shell(['docker','ps','-aq']).split()
    return json.loads(shell(['docker','inspect',*ids]))
def other_baseline(data):
    return {x['Id']:{'restart':x['RestartCount'],'oom':x['State']['OOMKilled'], 'state':x['State']['Status']}
            for x in data if x['Name'] != '/contextra-analytics-1'}

if __name__ == '__main__':
    assert not (R/'gate.json').exists()
    assert shell(['git','-C',str(REPO),'rev-parse','HEAD']).strip() == HEAD
    assert not shell(['git','-C',str(REPO),'status','--porcelain']).strip()
    free = shutil.disk_usage('/').free
    assert free >= 25*1024**3
    active = subprocess.run(['pgrep','-f',r'(^|/)docker (build|buildx build|pull)'],capture_output=True,text=True)
    assert active.returncode == 1
    collision = subprocess.run(['docker','image','inspect',TAG],capture_output=True)
    assert collision.returncode != 0
    data = inspect_all()
    c = next(x for x in data if x['Name']=='/contextra-analytics-1')
    assert c['State']['Status']=='exited' and not c['State']['OOMKilled'] and c['RestartCount']==0
    assert c['Image']=='sha256:e2137309461015890de735ccdfde452aaa4809ef58c107858c672c72762cd239'
    env = load_env_file(str(ENV))
    assert env['CONTEXTRA_IMAGE']=='contextra-analytics:surface-9d6b2c5-a8e9afcc'
    assert sha(CFG)=='5e5a4d22786f8b5218ac821379fbec091d9e3006f62c880ee3e3da5ced2f0e0b'
    assert sha(CFG.parent/'2/model.plan')=='5fdf1e9c55ab947a3b7d5f7f6bdceaf1e36a9e52efdf86f5a15d3b99b8631d1e'
    overlay=pathlib.Path(env['CONTEXTRA_RUNTIME_STATE_ROOT'])/'streams_runtime.yaml'
    specs=yaml.safe_load(overlay.read_text())['added']; assert len(specs)==1
    s=specs[0]
    assert all(s[x] is False for x in ['store','active_learning','autostart']) and s['scenarios']=='off'
    assert s['inference_profile']['roles']==['det'] and s['inference_profile']['det_model']=='RFDETRMedium'
    validate_deployment_inputs(str(ENV))
    gpu=int(shell(['nvidia-smi','--id=0','--query-gpu=memory.used','--format=csv,noheader,nounits']).strip())
    assert gpu<16384
    g={'head':HEAD,'tag':TAG,'env_hash':sha(ENV),'config_hash':sha(CFG),'overlay_hash':sha(overlay),
       'plan_hash':sha(CFG.parent/'2/model.plan'),'old_image':c['Image'],'old_tag':env['CONTEXTRA_IMAGE'],
       'other_containers':other_baseline(data),'analytics_state':c['State']['Status'],
       'disk_free_bytes':free,'gpu_used_mib':gpu,'test_count':1,'status':'PASS'}
    (R/'gate.json').write_text(json.dumps(g,indent=2))
    print(json.dumps({k:v for k,v in g.items() if k!='other_containers'}))
