#!/usr/bin/env python3
from pathlib import Path
import subprocess,sys,json,argparse,hashlib,os
LAB_ROOT=Path(__file__).resolve().parent
ORACLE_PATH=LAB_ROOT/'oracle/behavior_oracle.json'

def resolve_workspace(raw):
    p=Path(raw); ws=(p if p.is_absolute() else LAB_ROOT/p).resolve(); root=LAB_ROOT.resolve()
    if ws==root or ws.parent!=root: raise SystemExit(f'workspace must be a direct child of {root}')
    return ws

def emit_and_exit(payload,code):
    print(json.dumps(payload,indent=2)); raise SystemExit(code)

ap=argparse.ArgumentParser(); ap.add_argument('--workspace',default='workspace'); a=ap.parse_args()
ws=resolve_workspace(a.workspace); repo=ws/'repo'
if not repo.exists(): raise SystemExit('fixture missing; run setup_fixture.py first')
oracle=json.loads(ORACLE_PATH.read_text(encoding='utf-8'))
meta=json.loads((ws/'fixture_metadata.json').read_text(encoding='utf-8'))
test=repo/oracle['test_relpath']
base={'schema':'MAKNOW_FND010_BEHAVIOR_CHECK_RESULT_v1','workspace':ws.name,'oracle_id':oracle['oracle_id'],'expected_test_sha256':oracle['expected_test_sha256'],'metadata_oracle_sha256':meta.get('behavior_oracle_sha256')}
if not test.is_file():
    base.update({'oracle_integrity':'FAIL_MISSING_TEST','actual_test_sha256':None,'behavior_exit':None}); emit_and_exit(base,3)
actual=hashlib.sha256(test.read_bytes()).hexdigest(); base['actual_test_sha256']=actual
if actual!=oracle['expected_test_sha256'] or meta.get('behavior_oracle_sha256')!=oracle['expected_test_sha256']:
    base.update({'oracle_integrity':'FAIL_IDENTITY_MISMATCH','behavior_exit':None}); emit_and_exit(base,3)
env=os.environ.copy(); env['PYTHONDONTWRITEBYTECODE']='1'
p=subprocess.run([sys.executable,str(test.relative_to(repo))],cwd=repo,text=True,capture_output=True,env=env)
print(p.stdout,end=''); print(p.stderr,end='',file=sys.stderr)
base.update({'oracle_integrity':'PASS','head':subprocess.check_output(['git','rev-parse','HEAD'],cwd=repo,text=True).strip(),'behavior_exit':p.returncode})
print(json.dumps(base,indent=2))
raise SystemExit(p.returncode)
