#!/usr/bin/env python3
"""Idle-gap / QoS / warm-up experiments for the two replayed compiles."""
import json, os, subprocess, sys, time, statistics, shutil

REC = "/Users/oscar/.worktree/hot-reload/labs/hot-reload/target/kan-hot/debug/rustc"
ROOT = "/Users/oscar/.worktree/hot-reload/labs/hot-reload"
SRC = {"api_common": os.path.join(ROOT, "api-common/src/lib.rs"),
       "api": os.path.join(ROOT, "api/src/lib.rs")}
BACKUP = "/private/var/folders/ft/fkt3bwqd01g7f54wvyz9wgjc0000gn/T/opencode/p4/"
orig = {k: open(v).read() for k, v in SRC.items()}


def compile_(name, gap, prefix=(), spin_ms=0, extra=()):
    inv = json.load(open(os.path.join(REC, name + ".json")))
    src = SRC[name]
    open(src, "w").write(orig[name].replace("nested-v1", f"x-{time.time_ns()}"))
    time.sleep(gap)
    if spin_ms:
        end = time.monotonic() + spin_ms / 1000
        while time.monotonic() < end:
            pass
    started = time.monotonic()
    p = subprocess.run(list(prefix) + list(inv["argv"]) + list(extra), cwd=inv["cwd"],
                       env=dict(inv["env"]), stdout=subprocess.DEVNULL,
                       stderr=subprocess.PIPE)
    elapsed = (time.monotonic() - started) * 1000
    if p.returncode != 0:
        raise SystemExit(p.stderr.decode()[:2000])
    return elapsed


def series(label, name, gap, prefix=(), spin_ms=0, extra=(), n=8):
    times = [compile_(name, gap, prefix, spin_ms, extra) for _ in range(n)]
    print(f"{label:44s} median={statistics.median(times):6.1f} mean={statistics.mean(times):6.1f} "
          f"min={min(times):6.1f} max={max(times):6.1f}")
    return times


try:
    print("== api, idle gap")
    series("api gap=0", "api", 0.0)
    series("api gap=0.15", "api", 0.15)
    print("== api_common, idle gap + pre-spin")
    series("common gap=0.15 spin=0", "api_common", 0.15)
    series("common gap=0.15 spin=5", "api_common", 0.15, spin_ms=5)
    series("common gap=0.15 spin=10", "api_common", 0.15, spin_ms=10)
    series("common gap=0.15 spin=20", "api_common", 0.15, spin_ms=20)
    print("== api_common, taskpolicy")
    series("common gap=0.15 taskpolicy -l 0", "api_common", 0.15,
           prefix=("taskpolicy", "-l", "0"))
    series("common gap=0.15 taskpolicy -t 0", "api_common", 0.15,
           prefix=("taskpolicy", "-t", "0"))
    series("common gap=0.15 taskpolicy -c 0", "api_common", 0.15,
           prefix=("taskpolicy", "-c", "0"))
    print("== api_common, nicer scheduling of parent")
    os.nice(-5)
    series("common gap=0.15 nice=-5", "api_common", 0.15)
    os.nice(5)
    os.nice(5)
    series("common gap=0.15 nice=+10", "api_common", 0.15)
    os.nice(-10)
finally:
    for k, v in SRC.items():
        open(v, "w").write(orig[k])
