import json, os, signal, subprocess, sys, tempfile, time
from pathlib import Path

ROOT=Path(__file__).parent
FIXTURE=ROOT/'runtime_fixture.py'

def wait_for(p,timeout=3):
    end=time.time()+timeout
    while time.time()<end:
        if p.exists(): return
        time.sleep(0.02)
    raise RuntimeError(f'timeout waiting for {p.name}')

def launch_and_stop(sig,umask='0022',stop_delay_ms=0):
    with tempfile.TemporaryDirectory(prefix='ops001_lab_') as td:
        state=Path(td)/'state'; env=dict(os.environ); env['OPS001_STATE_DIR']=str(state)
        p=subprocess.Popen([sys.executable,str(FIXTURE),'--state-dir',str(state),'--umask',umask,'--stop-delay-ms',str(stop_delay_ms)],cwd=ROOT,env=env,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True)
        try:
            wait_for(state/'startup.json'); wait_for(state/'ready.json')
            startup=json.loads((state/'startup.json').read_text())
            os.kill(p.pid,sig)
            rc=p.wait(timeout=3)
            cleanup=(state/'cleanup.json').exists()
            return {'startup':startup,'signal':signal.Signals(sig).name,'returncode':rc,'cleanup_observed':cleanup,'ready_observed':(state/'ready.json').exists()}
        finally:
            if p.poll() is None: p.kill(); p.wait()

term=launch_and_stop(signal.SIGTERM,'0022')
kill=launch_and_stop(signal.SIGKILL,'0077')
print(json.dumps({'sigterm_case':term,'sigkill_case':kill},indent=2))
