#!/usr/bin/env python3
"""Does taskpolicy (latency tier) remove the idle-wake penalty for both compiles?"""
import json, os, subprocess, time, statistics

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")}
orig = {k: open(v).read() for k, v in SRC.items()}
INV = {k: json.load(open(os.path.join(REC, k + ".json"))) for k in SRC}


def compile_(name, prefix=()):
    inv = INV[name]
    started = time.monotonic()
    p = subprocess.run(list(prefix) + list(inv["argv"]), 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 seq(label, common_prefix=(), api_prefix=(), gap=0.15, n=8, spin_ms=0):
    cs, as_ = [], []
    for i in range(n):
        open(SRC["api_common"], "w").write(orig["api_common"].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
        cs.append(compile_("api_common", common_prefix))
        as_.append(compile_("api", api_prefix))
    c, a = statistics.median(cs), statistics.median(as_)
    print(f"{label:44s} common={c:6.1f} api={a:6.1f} total={c + a:6.1f} "
          f"min={min(cs) + min(as_):6.1f} max={max(cs) + max(as_):6.1f}")


try:
    seq("default")
    seq("taskpolicy -l 0 both", ("taskpolicy", "-l", "0"), ("taskpolicy", "-l", "0"))
    seq("taskpolicy -t 0 both", ("taskpolicy", "-t", "0"), ("taskpolicy", "-t", "0"))
    seq("taskpolicy -l 0 common only", ("taskpolicy", "-l", "0"))
    seq("spin 10ms before common", spin_ms=10)
    seq("spin 20ms before common", spin_ms=20)
finally:
    for k, v in SRC.items():
        open(v, "w").write(orig[k])
