#!/usr/bin/env python3
from pathlib import Path
import argparse, subprocess, shutil, sys, json, re, os
p=argparse.ArgumentParser()
p.add_argument('--dsn',required=True)
p.add_argument('--solution',default=str(Path(__file__).resolve().parents[1]/'sql/solution.sql'))
p.add_argument('--report',default=str(Path(__file__).resolve().parents[1]/'evidence/runtime-report.json'))
args=p.parse_args()
if not shutil.which('psql'): raise SystemExit('psql is required for the runtime phase.')
root=Path(__file__).resolve().parents[1]; sol=Path(args.solution); report_path=Path(args.report)
if not sol.exists(): raise SystemExit(f'Create your own {sol.name} first; the starter intentionally does not contain the solution.')
base=['psql',args.dsn,'-X','-v','ON_ERROR_STOP=1']
env=dict(os.environ); env.setdefault('PGAPPNAME','maknow-dat001-lab')
def run_file(path):
    return subprocess.run(base+['-f',str(path)],text=True,capture_output=True,env=env)
def run_sql(sql):
    return subprocess.run(base+['-c',sql],text=True,capture_output=True,env=env)
# Schema and valid seed must succeed before any negative probe can be interpreted.
for path in [sol,root/'sql/seed_valid.sql']:
    r=run_file(path)
    if r.returncode:
        print(r.stdout); print(r.stderr,file=sys.stderr); raise SystemExit(r.returncode)
vr=subprocess.run(base+['-At','-c','SHOW server_version;'],text=True,capture_output=True,env=env)
version=vr.stdout.strip() if vr.returncode==0 else 'UNAVAILABLE'
text=(root/'sql/probes.sql').read_text()
parts=re.split(r'(?m)^-- @probe ',text)[1:]
probes=[]
for part in parts:
    first,*rest=part.splitlines(); m=re.fullmatch(r'(\S+) expected=(ACCEPT|REJECT) dimension=(\S+)',first.strip())
    if not m: raise SystemExit(f'Invalid probe marker: {first!r}')
    pid,expected,dimension=m.groups(); sql='\n'.join(rest).strip()
    r=run_sql(sql); observed='ACCEPT' if r.returncode==0 else 'REJECT'
    probes.append({'id':pid,'dimension':dimension,'expected':expected,'observed':observed,'pass':observed==expected,'stdout':r.stdout.strip(),'stderr':r.stderr.strip()})
report={'schema':'DAT001_RUNTIME_PROBE_REPORT_v1','postgresql_version':version,'fabricated_runtime_evidence':False,'probe_count':len(probes),'passed':sum(x['pass'] for x in probes),'total':len(probes),'status':'PASS' if probes and all(x['pass'] for x in probes) else 'FAIL','probes':probes}
report_path.parent.mkdir(parents=True,exist_ok=True); report_path.write_text(json.dumps(report,ensure_ascii=False,indent=2)+'\n')
print(json.dumps({'status':report['status'],'postgresql_version':version,'passed':report['passed'],'total':report['total'],'report':str(report_path)},indent=2))
raise SystemExit(0 if report['status']=='PASS' else 1)
