"""Admission sample at window open. A SAMPLE, not a lease.

Two populations, because one cannot see the other (IR-100 third limit, todlando):
builders carry cargo/rustc/link names; a RUNNING TEST BINARY carries none of them,
so a clean builder census says nothing about executions in flight. Each arm gets a
positive control, because a filter that cannot express its hunt returns a clean zero.
"""
import json, os, subprocess, sys, time
import psutil
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import lane_run as L

DEPS = os.path.join(L.POOL, "debug", "deps")


def running_from_pool():
    """Processes whose IMAGE lives in this lane's deps dir - the executions the
    builder census is structurally blind to."""
    hits, unreadable = [], []
    for p in psutil.process_iter(["pid", "name", "create_time"]):
        try:
            exe = p.exe() or ""
        except (psutil.Error, OSError) as err:
            try:
                unreadable.append({"pid": p.info["pid"], "name": p.info["name"],
                                   "error": type(err).__name__})
            except Exception:
                unreadable.append({"pid": None, "name": None,
                                   "error": type(err).__name__})
            continue
        if not exe:
            # An EMPTY path is a BLIND SPOT, not a miss. psutil returns "" for a
            # few processes instead of raising, and the old filter skipped those
            # silently - they were counted nowhere and read exactly like "not in
            # the pool". Measured 2026-09-11: 556 processes, 553 readable, 1
            # raised, 2 empty. The hole was 3, and it was reported as 1.
            unreadable.append({"pid": p.info["pid"], "name": p.info["name"],
                               "error": "EmptyPath"})
            continue
        if os.path.normcase(exe).startswith(os.path.normcase(DEPS)):
            hits.append({"pid": p.info["pid"], "exe": exe,
                         "birth": p.info["create_time"]})
    return {"running": hits, "unreadable": unreadable}


SLEEPER = os.path.join(os.environ.get("SystemRoot", r"C:\Windows"),
                       "System32", "ping.exe")
LIVE_ARGS = ["-n", "8", "127.0.0.1"]   # ~7 s of life, no network egress


def _sleeper_named(directory, name):
    """A process that LIVES, wearing the name/path the filter under test keys on.

    First attempt used `cargo --version` and a real test binary's `--list`: both
    are correct subjects and both EXITED before either filter could sample them,
    so both controls read false and the sample's clean zero proved nothing. A
    control has to outlive the poll, so the sleeper is copied under the name
    (builder census keys on NAME) or into the directory (pool filter keys on PATH).
    """
    os.makedirs(directory, exist_ok=True)
    dst = os.path.join(directory, name)
    import shutil
    shutil.copyfile(SLEEPER, dst)
    return dst


def control_builder():
    """A process NAMED cargo.exe that lives; the census keys on the name."""
    ctl = _sleeper_named(os.path.join(L.EVID, "temp", "control"), "cargo.exe")
    p = subprocess.Popen([ctl] + LIVE_ARGS, stdout=subprocess.DEVNULL,
                         stderr=subprocess.DEVNULL)
    seen = False
    for _ in range(200):
        if any(b["pid"] == p.pid for b in L.builder_census()["builders"]):
            seen = True
            break
        if p.poll() is not None:
            break
        time.sleep(0.01)
    p.kill(); p.wait()
    try:
        os.remove(ctl)
    except OSError:
        pass
    return {"pid": p.pid, "control": ctl, "seen_by_census": seen}


def control_pool_exe():
    """A process whose IMAGE sits in deps and lives; the filter keys on path."""
    if not os.path.isdir(DEPS):
        return {"skipped": "deps dir absent", "seen_by_filter": None}
    exe = _sleeper_named(DEPS, "zz-admission-control.exe")
    p = subprocess.Popen([exe] + LIVE_ARGS, stdout=subprocess.DEVNULL,
                         stderr=subprocess.DEVNULL)
    seen = False
    for _ in range(300):
        if any(h["pid"] == p.pid for h in running_from_pool()["running"]):
            seen = True
            break
        if p.poll() is not None:
            break
        time.sleep(0.01)
    p.kill(); p.wait()
    try:
        os.remove(exe)
    except OSError:
        pass
    return {"exe": exe, "pid": p.pid, "seen_by_filter": seen}


if __name__ == "__main__":
    out = {
        "utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        "free_bytes": L.free_bytes(),
        "pool": L.pool_bytes(),
        "builders": L.builder_census(),
        "pool_executions": running_from_pool(),
        "control_builder": control_builder(),
        "control_pool_exe": control_pool_exe(),
    }
    json.dump(out, open(os.path.join(L.EVID, "admission-61bfd85c.json"), "w"), indent=2)
    print(json.dumps({k: out[k] for k in
                      ("utc", "free_bytes", "control_builder", "control_pool_exe")}, indent=2))
    print("by_owner:", out["builders"]["by_owner"])
    print("pool_executions:", len(out["pool_executions"]["running"]),
          "unreadable:", len(out["pool_executions"]["unreadable"]),
          out["pool_executions"]["unreadable"])
    for b in out["builders"]["builders"]:
        print("  builder", b["pid"], b["name"], b["owner"], b["manifest"])
    for h in out["pool_executions"]["running"]:
        print("  exec", h["pid"], h["exe"])
