import os,subprocess,time,threading
ROOT="/Users/oscar/.worktree/hot-reload/labs/hot-reload"; CLI="/Users/oscar/.worktree/hot-reload/target/debug/kan-hot-dev"
API=os.path.join(ROOT,"api","src","lib.rs"); COMMON=os.path.join(ROOT,"api-common","src","lib.rs")
env=dict(os.environ,RUST_LOG="error",KAN_HOT_EXAMPLE_INTERVAL_MS="300")
p=subprocess.Popen([CLI,"run","--bin","server","--lib","api"],cwd=ROOT,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,env=env,text=True,bufsize=1)
lines=[]; lock=threading.Lock()
def rd():
    for l in p.stdout:
        with lock: lines.append((time.monotonic(),l))
threading.Thread(target=rd,daemon=True).start()
def wait(pred,after=0,to=40):
    d=time.monotonic()+to
    while time.monotonic()<d:
        with lock:
            for t,l in lines[after:]:
                if pred(l): return t,l
        time.sleep(.005)
    raise TimeoutError
api=open(API).read(); common=open(COMMON).read()
try:
    wait(lambda l:"gen 1 hello" in l)
    with lock: n=len(lines)
    dup=api.replace('        .query("count",', '        .query("hello", |_state: &AppState, _: ()| async move { "duplicate".to_string() })\n        .query("count",')
    open(API,"w").write(dup)
    wait(lambda l:"the previous generation is still active" in l, after=n, to=60)
    print("builder panic recovered, previous generation kept")
    with lock: n2=len(lines)
    open(API,"w").write(api)
    open(COMMON,"w").write(common.replace("nested-v1","after-panic"))
    t,l=wait(lambda l:'"nested":"after-panic"' in l, after=n2, to=60)
    print("reload after panic succeeded:",l.strip()[:120])
finally:
    open(API,"w").write(api); open(COMMON,"w").write(common); time.sleep(1)
    try: p.stdin.write("q\n");p.stdin.flush();p.wait(timeout=15)
    except Exception: p.kill()
