"""Kill port 8001 holders, then start ai-service."""
from __future__ import annotations

import os
import subprocess
import sys
import time
import urllib.request
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
LOG = ROOT / ".runtime" / "logs"
LOG.mkdir(parents=True, exist_ok=True)


def pids_on_port(port: int) -> list[int]:
    out = subprocess.check_output(["netstat", "-ano"], text=True, errors="replace")
    pids: set[int] = set()
    needle = f":{port}"
    for line in out.splitlines():
        if needle not in line:
            continue
        if "LISTENING" not in line.upper():
            continue
        parts = line.split()
        try:
            pids.add(int(parts[-1]))
        except ValueError:
            pass
    return sorted(pids)


def kill_pid(pid: int) -> None:
    if pid <= 0:
        return
    subprocess.run(["taskkill", "/F", "/T", "/PID", str(pid)], check=False, capture_output=True)


def main() -> None:
    print("stopping old ai...")
    # stop watchdog first if present
    wd = LOG / "watchdog.pid"
    if wd.is_file():
        try:
            kill_pid(int(wd.read_text(encoding="ascii").strip()))
        except ValueError:
            pass
        wd.unlink(missing_ok=True)

    for name in ("ai-service.pid",):
        pf = LOG / name
        if pf.is_file():
            try:
                kill_pid(int(pf.read_text(encoding="ascii").strip()))
            except ValueError:
                pass

    for pid in pids_on_port(8001):
        print(f"  free 8001 pid={pid}")
        kill_pid(pid)
    time.sleep(2)

    env = os.environ.copy()
    env["WEB_BASE"] = "http://127.0.0.1:5173"
    env["PLATFORM_BASE"] = "http://127.0.0.1:8888"
    env["GATEWAY_BASE"] = "http://127.0.0.1:8180"
    env["GENERATE_LOG_DIR"] = str(LOG / "generate")
    env["FIDELITY_SHOT_DIR"] = str(ROOT / ".runtime" / "fidelity_shots")

    stamp = time.strftime("%H%M%S")
    out_path = LOG / f"ai-service.{stamp}.out.log"
    err_path = LOG / f"ai-service.{stamp}.err.log"
    out_f = out_path.open("w", encoding="utf-8")
    err_f = err_path.open("w", encoding="utf-8")
    # also point stable names via copies later; use unique to avoid locks
    (LOG / "ai-service.out.log.path").write_text(str(out_path), encoding="utf-8")

    flags = getattr(subprocess, "CREATE_NO_WINDOW", 0)
    p = subprocess.Popen(
        [
            sys.executable,
            "-m",
            "uvicorn",
            "app:app",
            "--host",
            "127.0.0.1",
            "--port",
            "8001",
            "--reload",
        ],
        cwd=str(ROOT / "ai-service"),
        env=env,
        stdout=out_f,
        stderr=err_f,
        creationflags=flags,
    )
    (LOG / "ai-service.pid").write_text(str(p.pid), encoding="ascii")
    print(f"started ai-service pid={p.pid}")
    print(f"  logs: {out_path.name} / {err_path.name}")

    for i in range(45):
        time.sleep(1)
        try:
            with urllib.request.urlopen("http://127.0.0.1:8001/docs", timeout=2) as r:
                if r.status == 200:
                    print("OK  AI http://127.0.0.1:8001")
                    return
        except Exception as e:
            if i % 5 == 4:
                print(f"  waiting... ({type(e).__name__})")
                # show err log snippet
                try:
                    print(err_path.read_text(encoding="utf-8", errors="replace")[-400:])
                except Exception:
                    pass
    raise SystemExit("AI failed to become ready on :8001")


if __name__ == "__main__":
    main()
