"""Finite one-worker runner; only fixed study modes, immutable attempt records."""
import argparse, datetime, json, os, pathlib, resource, signal, subprocess, time
ROOT=pathlib.Path(__file__).resolve().parent

def main():
    p=argparse.ArgumentParser();p.add_argument('mode',choices=['fixtures','freeze','smoke','full','rerun']);a=p.parse_args()
    ledger=ROOT/'attempts.json';old=json.loads(ledger.read_text()) if ledger.exists() else []
    base_cpu,base_wall=200.44612,171.78210
    cpu=base_cpu+sum(x['cpu_seconds'] for x in old);wall=base_wall+sum(x['wall_seconds'] for x in old)
    timeout=300 if a.mode=='full' else 120
    if cpu+timeout>3600 or wall+timeout>5400:raise SystemExit('aggregate reservation unavailable')
    env=dict(os.environ,OMP_NUM_THREADS='1',OPENBLAS_NUM_THREADS='1',MKL_NUM_THREADS='1',VECLIB_MAXIMUM_THREADS='1',NUMEXPR_NUM_THREADS='1',PYTHONDONTWRITEBYTECODE='1')
    def limits():
        os.setsid();resource.setrlimit(resource.RLIMIT_CPU,(timeout,timeout+1))
        resource.setrlimit(resource.RLIMIT_FSIZE,(32*1024**2,32*1024**2))
    start=time.monotonic();usage=resource.getrusage(resource.RUSAGE_CHILDREN);stamp=datetime.datetime.now(datetime.timezone.utc).isoformat()
    log=ROOT/f'{len(old)+1:02d}-{a.mode}.log';reason=None;peak=0;sample_count=0
    with log.open('x') as output:
        child=subprocess.Popen(['python3','experiment.py',a.mode],cwd=ROOT,env=env,stdout=output,stderr=subprocess.STDOUT,preexec_fn=limits)
        while child.poll() is None:
            rows=subprocess.run(['ps','-axo','pid=,ppid=,rss='],capture_output=True,text=True).stdout.splitlines()
            table=[tuple(map(int,r.split())) for r in rows if len(r.split())==3]
            ids={child.pid}
            for _ in range(4):ids.update(pid for pid,ppid,rss in table if ppid in ids)
            rss=sum(rss*1024 for pid,ppid,rss in table if pid in ids);peak=max(peak,rss);sample_count+=1
            if rss>1024**3:reason='RSS ceiling'
            if time.monotonic()-start>timeout:reason='wall ceiling'
            if sum(f.stat().st_size for f in ROOT.rglob('*') if f.is_file())>128*1024**2:reason='artifact ceiling'
            if reason:os.killpg(child.pid,signal.SIGKILL);break
            time.sleep(.1)
        rc=child.wait()
    end=resource.getrusage(resource.RUSAGE_CHILDREN)
    rec=dict(mode=a.mode,started_utc=stamp,returncode=rc,failure=reason,
        cpu_seconds=end.ru_utime+end.ru_stime-usage.ru_utime-usage.ru_stime,
        wall_seconds=time.monotonic()-start,peak_sampled_tree_rss_bytes=peak,samples=sample_count,
        timeout_seconds=timeout,threads=1,memory_enforcement='100 ms sampled child-tree RSS watchdog; no instantaneous hard RSS/address-space guarantee',
        inherited_and_reserved_cpu_seconds=base_cpu,inherited_and_reserved_wall_seconds=base_wall)
    old.append(rec);ledger.write_text(json.dumps(old,indent=2)+'\n')
    print(log.read_text()[-7000:]);print(json.dumps(rec));raise SystemExit(rc if rc else bool(reason))
if __name__=='__main__':main()
