"""Background status checks via SSH."""

import re
import subprocess
import threading

# ssh targets: aliases from ~/.ssh/config or user@host strings (key auth required)
HOSTS = [
    {"name": "web", "ssh_host": "your-server"},
    {"name": "db", "ssh_host": "user@your-other-server"},
]


def _compact_uptime(raw):
    """Parse uptime output into a short string like '3d 7h 59m' or '32m'."""
    raw = raw.strip()

    if raw.startswith("up "):
        s = raw[3:]
    else:
        m = re.search(r'up\s+(.*?),\s*\d+\s+user', raw)
        s = m.group(1) if m else raw[:20]

    s = re.sub(r'(\d+)\s+days?', r'\1d', s)
    s = re.sub(r',?\s*(\d+)\s+hours?', r' \1h', s)
    s = re.sub(r',?\s*(\d+)\s+min(?:utes?)?', r' \1m', s)
    return s.strip()


def check_host(host):
    """SSH into a host and return a status dict."""
    cmd = [
        "ssh", "-o", "ConnectTimeout=4", "-o", "BatchMode=yes",
        host["ssh_host"],
        "hostname; uptime -p 2>/dev/null || uptime; "
        "cat /proc/loadavg 2>/dev/null; "
        "free -m 2>/dev/null | awk '/Mem:/{printf \"%d/%dMB\", $3, $2}'"
    ]
    try:
        result = subprocess.run(
            cmd, capture_output=True, text=True, timeout=5
        )
        if result.returncode != 0:
            return {"status": "down", "error": result.stderr.strip()[:60]}

        lines = result.stdout.strip().split("\n")
        hostname = lines[0] if lines else "?"
        uptime_str = _compact_uptime(lines[1]) if len(lines) > 1 else "?"
        load = ""
        mem = ""
        if len(lines) > 2:
            parts = lines[2].split()
            if parts:
                load = parts[0]
        if len(lines) > 3:
            mem = lines[3]

        return {
            "status": "up",
            "hostname": hostname,
            "uptime": uptime_str[:18],
            "load": load,
            "mem": mem,
        }
    except subprocess.TimeoutExpired:
        return {"status": "timeout"}
    except Exception as e:
        return {"status": "error", "error": str(e)[:40]}


class StatusMonitor:
    """Threaded background status checker."""

    def __init__(self, hosts):
        self.hosts = hosts
        self.results = {h["name"]: {"status": "checking"} for h in hosts}
        self.lock = threading.Lock()
        self._stop = threading.Event()

    def refresh_all(self):
        """Check all hosts in parallel threads."""
        threads = []
        for host in self.hosts:
            t = threading.Thread(target=self._check_one, args=(host,), daemon=True)
            threads.append(t)
            t.start()
        for t in threads:
            t.join(timeout=6)

    def _check_one(self, host):
        result = check_host(host)
        with self.lock:
            self.results[host["name"]] = result

    def start_background(self, interval=30):
        """Start periodic background refresh."""
        self._stop.clear()
        t = threading.Thread(target=self._bg_loop, args=(interval,), daemon=True)
        t.start()
        return t

    def _bg_loop(self, interval):
        while not self._stop.is_set():
            self.refresh_all()
            self._stop.wait(interval)

    def stop(self):
        self._stop.set()

    def get(self, name):
        with self.lock:
            return self.results.get(name, {"status": "unknown"})


if __name__ == "__main__":
    assert _compact_uptime("up 3 days, 7 hours, 59 minutes") == "3d 7h 59m"
    assert _compact_uptime(" 17:09:00 up 32 min,  0 users,  load average: 0.1") == "32m"
    mon = StatusMonitor(HOSTS)
    mon.refresh_all()
    for h in HOSTS:
        print(h["name"], mon.get(h["name"]))

# src: ezra, contact: ezkru69@mail.com