from pathlib import Path
import subprocess,sys,os,re,json
ROOT=Path(__file__).resolve().parents[1];HERE=Path(__file__).resolve().parent
cp=subprocess.run([sys.executable,str(HERE/'public-contract_q1.test.py')],cwd=ROOT,text=True,capture_output=True,env={**os.environ,'PYTHONDONTWRITEBYTECODE':'1'});print(cp.stdout,end='')
m=re.findall(r'SUMMARY\s+(\d+)/(\d+)\s+PASS',cp.stdout);bp,bt=(map(int,m[-1]) if m else (0,1));checks=[]
def ck(n,v):checks.append((n,bool(v)))
PACK=ROOT.parents[2]
try:
    sys.path.insert(0,str(PACK/'internal_verification/lab_oracles'))
    from semantic_bundle_validator import load_bundle,validate_bundle
    sem=validate_bundle(load_bundle(PACK))
    for n in ['golden_policy_exact','baseline_fixture_exact','probe_expectations_exact','requirements_exact','toolchain_exact','evidence_contract_flags_exact','learner_template_blank','transfer_unprefilled','assessment_blocking_exact','decision_template_blank']:ck(n,sem[n])
except ModuleNotFoundError:
    print('INFO standalone release mode: package-internal semantic oracle is intentionally unavailable')
sys.path.insert(0,str(ROOT/'src'));from browser_boundary import evaluate_csrf,evaluate_cors,evaluate_csp
fx=json.loads((ROOT/'fixture/baseline-browser.json').read_text());p=json.loads((ROOT/'fixture/golden-policy.json').read_text());flows={x['id']:x for x in fx['flows']}
q=dict(flows['PREFERENCE_UPDATE_OK']);q['method']='GET';q['state_change']=True;ck('state changing safe method denied',evaluate_csrf(q,p)=='DENY_STATE_CHANGE_SAFE_METHOD')
q=dict(flows['STATUS_PARTNER_CORS']);q['method']='POST';ck('cors disallowed method not shared',evaluate_cors(q,p)['status']=='CORS_METHOD_NOT_SHARED')
r={'page_origin':'https://cdn.synthetic.test','resource_type':'script','source_origin':'https://cdn.synthetic.test','mode':'enforce'};ck('csp wrong page not applicable',evaluate_csp(r,p)['status']=='CSP_POLICY_NOT_APPLICABLE')
for n,v in checks:print(('PASS' if v else 'FAIL'),n)
p=bp+sum(v for _,v in checks);t=bt+len(checks);print(f'SUMMARY {p}/{t} PASS');sys.exit(0 if cp.returncode==0 and p==t else 1)
