#!/usr/bin/env python3
"""Standalone replay harness: mimics build_hot without link/load."""
import json, subprocess, sys, time, threading, statistics, os

ROOT = "/Users/oscar/.worktree/hot-reload/labs/hot-reload"
SRC = os.path.join(ROOT, "api-common/src/lib.rs")
AC = json.load(open(os.path.join(ROOT, "target/kan-hot/debug/rustc/api_common.json")))
AP = json.load(open(os.path.join(ROOT, "target/kan-hot/debug/rustc/api.json")))
INCR = os.path.join(ROOT, "target/kan-hot/debug/incremental")

AC_REPLAY = AC["argv"] + ["-C", "debuginfo=0", "-C", "codegen-units=8",
                          "-C", f"incremental={INCR}/api_common"]
AP_REPLAY = AP["argv"] + ["-C", "debuginfo=0", "-C", "codegen-units=8",
                          "-C", f"incremental={INCR}/api"]

def strip_flag(argv, name):
    out = []; i = 0
    while i < len(argv):
        if argv[i] == "-C" and i + 1 < len(argv) and argv[i + 1].startswith(name):
            i += 2; continue
        if argv[i].startswith("-C" + name):
            i += 1; continue
        out.append(argv[i]); i += 1
    return out

def set_cu(argv, cu):
    return strip_flag(argv, "codegen-units=") + ["-C", f"codegen-units={cu}"]

VARIANTS = {
    "recorded": (AC_REPLAY, AP_REPLAY),
}

def run(argv, env, cwd):
    t = time.monotonic()
    r = subprocess.run(argv, cwd=cwd, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    return (time.monotonic() - t) * 1000, r.returncode

_stop = False
def warmer(deadline):
    # emulate a persistently warm core
    while not _stop:
        if time.monotonic() < deadline[0]:
            for _ in range(10000):
                pass
        else:
            time.sleep(0.005)

def main():
    n = int(sys.argv[2]) if len(sys.argv) > 2 else 8
    names = sys.argv[1].split(",")
    env = dict(AC["env"])
    env["RUSTC_BOOTSTRAP"] = env.get("RUSTC_BOOTSTRAP", "")
    original = open(SRC).read()
    deadline = [0.0]
    thread = threading.Thread(target=warmer, args=(deadline,), daemon=True)
    thread.start()
    results = {}
    try:
        for name in names:
            acv, apv = VARIANTS[name]
            totals = []
            for i in range(n):
                marker = f"exp-{name}-{i}-{time.time_ns()}"
                open(SRC, "w").write(original.replace("nested-v1", marker))
                deadline[0] = time.monotonic() + 3.0
                time.sleep(0.15)
                t0 = time.monotonic()
                d1, rc1 = run(acv, env, AC["cwd"])
                d2, rc2 = run(apv, env, AP["cwd"])
                totals.append(((time.monotonic() - t0) * 1000, d1, d2))
                if rc1 or rc2:
                    print("FAIL", name, rc1, rc2)
                time.sleep(0.15)
            results[name] = totals
    finally:
        open(SRC, "w").write(original)
        _stop = True
    for name, totals in results.items():
        whole = [x[0] for x in totals]
        print(f"{name:14s} total med={statistics.median(whole):6.1f} mean={statistics.mean(whole):6.1f} "
              f"min={min(whole):6.1f} max={max(whole):6.1f} | "
              f"ac={statistics.median([x[1] for x in totals]):5.1f} "
              f"api={statistics.median([x[2] for x in totals]):5.1f}")

if __name__ == "__main__":
    main()
