#!/usr/bin/env python3
import os, subprocess, time, statistics, shlex, re

LAB = "/Users/oscar/.worktree/hot-reload/labs/hot-reload"
SRC = os.path.join(LAB, "api-common/src/lib.rs")
WRAPPER = "/Users/oscar/.worktree/hot-reload/target/debug/kan-hot-dev"
TLIB = subprocess.check_output(["rustc", "--print", "target-libdir"], text=True).strip()
BASE = dict(
    os.environ,
    RUSTC_WORKSPACE_WRAPPER=WRAPPER,
    KAN_HOT_WRAPPER_HOST="server",
    KAN_HOT_WRAPPER_HOT="api,api_common",
    KAN_HOT_RUNTIME_LIBS_FILE="/private/var/folders/ft/fkt3bwqd01g7f54wvyz9wgjc0000gn/T/opencode/link-exp/runtime.txt",
    KAN_HOT_TARGET_LIBDIR=TLIB,
)

original = open(SRC).read()

# Capture the rustc command lines cargo uses.
open(SRC, "w").write(original.replace("nested-v1", "nested-c1"))
p = subprocess.run(["cargo", "build", "-p", "api", "-p", "server", "--lib", "-v"],
                   cwd=LAB, env=BASE, text=True, capture_output=True)
open(SRC, "w").write(original)
lines = [l for l in p.stderr.splitlines() if "Running" in l and "--crate-name" in l]
cmds = {}
for line in lines:
    body = line.split("Running `", 1)[1].rsplit("`", 1)[0]
    argv = shlex.split(body)
    if argv[0] == "kache":
        argv = argv[1:]
    name = None
    for i, a in enumerate(argv):
        if a == "--crate-name":
            name = argv[i + 1]
    cmds[name] = argv
print("captured:", {k: len(v) for k, v in cmds.items()}, "wrapper?", cmds["api_common"][0])


def run_direct(marker):
    open(SRC, "w").write(original.replace("nested-v1", marker))
    start = time.monotonic()
    for name in ("api_common", "api"):
        r = subprocess.run(cmds[name], cwd=LAB, env=BASE,
                           stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
        if r.returncode != 0:
            print(r.stderr.decode()[:2000])
            raise SystemExit(f"{name} failed")
    return (time.monotonic() - start) * 1000


direct = []
cargo = []
for rep in range(5):
    direct.append(run_direct(f"nested-d{rep}"))
    open(SRC, "w").write(original.replace("nested-v1", f"nested-e{rep}"))
    start = time.monotonic()
    subprocess.run(["cargo", "build", "--message-format=json-render-diagnostics",
                    "-p", "api", "-p", "server", "--lib"],
                   cwd=LAB, env=BASE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    cargo.append((time.monotonic() - start) * 1000)

open(SRC, "w").write(original)
for name, vals in (("direct rustc", direct), ("cargo build", cargo)):
    print(f"{name:14} median={statistics.median(vals):6.1f} mean={statistics.mean(vals):6.1f} min={min(vals):6.1f} max={max(vals):6.1f} {[round(v) for v in vals]}")
