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

LAB = "/Users/oscar/.worktree/hot-reload/labs/hot-reload"
TLIB = subprocess.check_output(["rustc", "--print", "target-libdir"], text=True).strip()
STD = os.path.basename(glob.glob(TLIB + "/libstd-*.dylib")[0])[3:-6]
API = glob.glob(LAB + "/target/debug/deps/libapi-*.rlib")
AC = glob.glob(LAB + "/target/debug/deps/libapi_common-*.rlib")
API = max(API, key=os.path.getmtime)
AC = max(AC, key=os.path.getmtime)
print("api", API, "ac", AC, "std", STD)

out = "/private/var/folders/ft/fkt3bwqd01g7f54wvyz9wgjc0000gn/T/opencode/link-exp"
os.makedirs(out, exist_ok=True)

def cc_cmd(dest, dead):
    c = ["cc", "-dynamiclib", "-undefined", "dynamic_lookup"]
    if dead: c += ["-Wl,-dead_strip"]
    c += ["-Wl,-force_load," + API, "-Wl,-force_load," + AC, "-o", dest,
          "-L", TLIB, "-l" + STD, "-Wl,-rpath," + TLIB]
    return c

def ld_cmd(dest, dead, platform):
    c = ["ld", "-dylib", "-undefined", "dynamic_lookup"]
    if dead: c += ["-dead_strip"]
    if platform: c += ["-platform_version", "macos", "11.0", "0.0"]
    c += ["-force_load", API, "-force_load", AC, "-o", dest,
          "-L", TLIB, "-l" + STD, "-rpath", TLIB]
    return c

variants = {
    "cc_dead": lambda d: cc_cmd(d, True),
    "cc_nodead": lambda d: cc_cmd(d, False),
    "ld_dead": lambda d: ld_cmd(d, True, False),
    "ld_nodead": lambda d: ld_cmd(d, False, False),
    "ld_dead_platform": lambda d: ld_cmd(d, True, True),
    "ld_nodead_platform": lambda d: ld_cmd(d, False, True),
}
results = {k: [] for k in variants}
errors = {}
for rep in range(6):
    for name, make in variants.items():
        dest = f"{out}/{name}.dylib"
        start = time.monotonic()
        r = subprocess.run(make(dest), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        dt = (time.monotonic() - start) * 1000
        if r.returncode != 0:
            errors[name] = r.stderr.decode()[:300]
            break
        results[name].append(dt)
for name, vals in results.items():
    if vals:
        print(f"{name:22} median={statistics.median(vals):6.1f} mean={statistics.mean(vals):6.1f} size={os.path.getsize(out+'/'+name+'.dylib')} {[round(v) for v in vals]}")
    else:
        print(f"{name:22} FAILED {errors.get(name)}")
