"""
Install the Bluetooth + Wi-Fi dongle drivers shipped with the CSR-BT kernel
fix — IN-SHELL, console-free. Same pattern as netops/storageops: pure helpers
(testable off-device) + a tolerant live layer gated by backend.live_enabled().

The driver package (built by csr-fix CI: `wifi-modules/*.ko`, plus optionally a
patched `btusb.ko`) ships on the card. This copies the modules into the running
kernel's tree, regenerates the module DB (so the USB id→module alias exists and
the dongle auto-loads on boot), loads them, and reports whether a `wlan`
interface came up. Output is captured — nothing ever reaches a console/TUI; the
Drivers screen renders its own progress.

Mirrors tools/wifi_install.sh (the manual Ports installer) so verifying that
one verifies this path too.
"""

from __future__ import annotations

import glob
import os
import subprocess
from typing import Optional

_SUDO = [] if os.environ.get("AAHEAD_SUDO") == "0" else ["sudo", "-n"]
_TIMEOUT = 120


def kver() -> str:
    try:
        return os.uname().release
    except AttributeError:          # non-posix dev box
        return ""


def roms_root() -> str:
    return os.environ.get("AAHEAD_ROMS_ROOT") or "/roms"


def package_candidates() -> list[str]:
    """Where the driver package's `wifi-modules/` may live on the card."""
    gd = os.environ.get("AAHEAD_GAMEDIR") or ""
    r = roms_root()
    out = []
    for base in (gd, f"{r}/ports/aahead", f"{r}/ports"):
        if base:
            out.append(os.path.join(base, "drivers", "wifi-modules"))
            out.append(os.path.join(base, "wifi-modules"))
    return out


def find_package(candidates=None) -> Optional[str]:
    """First candidate dir that actually holds *.ko, else None."""
    for d in (candidates if candidates is not None else package_candidates()):
        try:
            if os.path.isdir(d) and glob.glob(os.path.join(d, "*.ko")):
                return d
        except OSError:
            continue
    return None


def driver_installed(modules_root="/lib/modules") -> bool:
    """Is the RTL8188FU module already in the running kernel's tree?"""
    base = os.path.join(modules_root, kver())
    if not os.path.isdir(base):
        return False
    for name in ("8188fu.ko", "rtl8188fu.ko"):
        if glob.glob(os.path.join(base, "**", name), recursive=True):
            return True
    return False


def wlan_up() -> bool:
    """Is there a wlan interface right now?"""
    r = _run(["ip", "-o", "link", "show"])
    if r is None:
        return False
    return any(" wl" in ln or ln.strip().split(":")[1:2] == [" wl"]
               for ln in r.stdout.splitlines() if "wl" in ln)


# ── live layer ────────────────────────────────────────────────────────

def _run(args, sudo=False, timeout=_TIMEOUT):
    cmd = ([*_SUDO] if sudo else []) + args
    try:
        return subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
    except (FileNotFoundError, subprocess.TimeoutExpired, OSError):
        return None


def run_install() -> Optional[dict]:
    """Install the bundled driver modules. Returns
    {ok, wlan_up, needs_reboot, error}. Blocking — call via call_async.
    Output captured → never hits a console."""
    src = find_package()
    if not src:
        return {"ok": False, "wlan_up": False, "needs_reboot": False,
                "error": "driver package not found on card"}
    kos = glob.glob(os.path.join(src, "*.ko"))
    kr = kver()
    dest = os.path.join("/lib/modules", kr, "kernel/drivers/net/wireless/aahead")

    # rootfs may be ro — flip rw for the copy (best-effort; restore after)
    _run(["mount", "-o", "remount,rw", "/"], sudo=True, timeout=20)
    if (_run(["mkdir", "-p", dest], sudo=True, timeout=20) is None):
        return None
    cp = _run(["cp", "-f", *kos, dest], sudo=True, timeout=60)
    if cp is None or cp.returncode != 0:
        _run(["mount", "-o", "remount,ro", "/"], sudo=True, timeout=20)
        return {"ok": False, "wlan_up": False, "needs_reboot": False,
                "error": "could not copy modules (rootfs read-only?)"}
    _run(["depmod", "-a", kr], sudo=True, timeout=60)
    # load the dongle drivers (8188fu is this device's; others are no-ops absent)
    for m in ("8188fu", "rtl8188fu", "8189fs", "8723bu", "8821cu", "8812au",
              "88x2bu", "8192cu", "mt7601u"):
        _run(["modprobe", m], sudo=True, timeout=20)
    _run(["mount", "-o", "remount,ro", "/"], sudo=True, timeout=20)

    up = wlan_up()
    return {"ok": True, "wlan_up": up, "needs_reboot": not up, "error": None,
            "count": len(kos)}
