"""Daemon installer — register AgntSpace as a system service.

Supports:
- Windows: nssm (Non-Sucking Service Manager) → Windows Service
- Linux: systemd unit file
- macOS: launchd plist

The service auto-starts on boot and auto-restarts on crash.
"""

from __future__ import annotations

import logging
import platform
import shutil
import subprocess
import sys
from pathlib import Path

log = logging.getLogger(__name__)

SERVICE_NAME = "agntspace"
SERVICE_DISPLAY = "AgntSpace Agent"
SERVICE_DESC = "Personal AI agent that runs your life alongside you."


def install_daemon(host: str = "127.0.0.1", port: int = 8000) -> str:
    """Install AgntSpace as a system service. Returns status message."""
    system = platform.system()
    if system == "Windows":
        return _install_windows(host, port)
    elif system == "Linux":
        return _install_linux(host, port)
    elif system == "Darwin":
        return _install_macos(host, port)
    else:
        return f"Unsupported platform: {system}"


def uninstall_daemon() -> str:
    """Remove AgntSpace system service. Returns status message."""
    system = platform.system()
    if system == "Windows":
        return _uninstall_windows()
    elif system == "Linux":
        return _uninstall_linux()
    elif system == "Darwin":
        return _uninstall_macos()
    else:
        return f"Unsupported platform: {system}"


def daemon_status() -> dict:
    """Check if the daemon is installed and running."""
    system = platform.system()
    result = {"platform": system, "installed": False, "running": False, "method": ""}

    if system == "Windows":
        result["method"] = "nssm (Windows Service)"
        try:
            out = subprocess.run(
                ["nssm", "status", SERVICE_NAME],
                capture_output=True, text=True, timeout=5,
            )
            if out.returncode == 0:
                result["installed"] = True
                result["running"] = "SERVICE_RUNNING" in out.stdout
        except (FileNotFoundError, subprocess.TimeoutExpired):
            pass

    elif system == "Linux":
        result["method"] = "systemd"
        unit_path = Path(f"/etc/systemd/system/{SERVICE_NAME}.service")
        result["installed"] = unit_path.exists()
        if result["installed"]:
            try:
                out = subprocess.run(
                    ["systemctl", "is-active", SERVICE_NAME],
                    capture_output=True, text=True, timeout=5,
                )
                result["running"] = out.stdout.strip() == "active"
            except (FileNotFoundError, subprocess.TimeoutExpired):
                pass

    elif system == "Darwin":
        result["method"] = "launchd"
        plist_path = Path.home() / f"Library/LaunchAgents/com.archerfutura.{SERVICE_NAME}.plist"
        result["installed"] = plist_path.exists()
        if result["installed"]:
            try:
                out = subprocess.run(
                    ["launchctl", "list", f"com.archerfutura.{SERVICE_NAME}"],
                    capture_output=True, text=True, timeout=5,
                )
                result["running"] = out.returncode == 0
            except (FileNotFoundError, subprocess.TimeoutExpired):
                pass

    return result


# ── Windows (nssm) ──


def _install_windows(host: str, port: int) -> str:
    nssm = shutil.which("nssm")
    if not nssm:
        return (
            "nssm not found. Install it first:\n"
            "  winget install nssm\n"
            "  or download from https://nssm.cc/download\n"
            "Then run this command again."
        )

    python = sys.executable
    args = f"-m agntspace.cli start --host {host} --port {port}"

    cmds = [
        [nssm, "install", SERVICE_NAME, python, args],
        [nssm, "set", SERVICE_NAME, "DisplayName", SERVICE_DISPLAY],
        [nssm, "set", SERVICE_NAME, "Description", SERVICE_DESC],
        [nssm, "set", SERVICE_NAME, "Start", "SERVICE_AUTO_START"],
        [nssm, "set", SERVICE_NAME, "AppStdout", str(Path.home() / ".agntspace/logs/service.log")],
        [nssm, "set", SERVICE_NAME, "AppStderr", str(Path.home() / ".agntspace/logs/service-error.log")],
        [nssm, "set", SERVICE_NAME, "AppRotateFiles", "1"],
        [nssm, "set", SERVICE_NAME, "AppRotateBytes", "5242880"],  # 5MB
        [nssm, "set", SERVICE_NAME, "AppRestartDelay", "5000"],  # 5s restart delay
    ]

    for cmd in cmds:
        try:
            subprocess.run(cmd, check=True, capture_output=True, text=True, timeout=10)
        except subprocess.CalledProcessError as e:
            return f"Failed: {' '.join(cmd)}\n{e.stderr}"

    # Start the service
    subprocess.run([nssm, "start", SERVICE_NAME], capture_output=True, timeout=10)

    return (
        f"AgntSpace installed as Windows Service '{SERVICE_NAME}'.\n"
        f"  Auto-starts on boot, auto-restarts on crash.\n"
        f"  Manage: nssm start/stop/restart {SERVICE_NAME}\n"
        f"  Logs: ~/.agntspace/logs/service.log"
    )


def _uninstall_windows() -> str:
    nssm = shutil.which("nssm")
    if not nssm:
        return "nssm not found."

    subprocess.run([nssm, "stop", SERVICE_NAME], capture_output=True, timeout=10)
    result = subprocess.run(
        [nssm, "remove", SERVICE_NAME, "confirm"],
        capture_output=True, text=True, timeout=10,
    )
    if result.returncode == 0:
        return f"Service '{SERVICE_NAME}' removed."
    return f"Failed to remove service: {result.stderr}"


# ── Linux (systemd) ──


def _install_linux(host: str, port: int) -> str:
    python = sys.executable
    unit = f"""[Unit]
Description={SERVICE_DISPLAY}
After=network.target

[Service]
Type=simple
ExecStart={python} -m agntspace.cli start --host {host} --port {port}
Restart=always
RestartSec=5
User={Path.home().name}
WorkingDirectory={Path.home()}
Environment=PATH={Path(python).parent}:/usr/bin:/bin

[Install]
WantedBy=multi-user.target
"""
    unit_path = Path(f"/etc/systemd/system/{SERVICE_NAME}.service")
    try:
        unit_path.write_text(unit)
    except PermissionError:
        return (
            f"Permission denied writing to {unit_path}.\n"
            f"Run with sudo: sudo agntspace install-daemon"
        )

    subprocess.run(["systemctl", "daemon-reload"], check=True, timeout=10)
    subprocess.run(["systemctl", "enable", SERVICE_NAME], check=True, timeout=10)
    subprocess.run(["systemctl", "start", SERVICE_NAME], check=True, timeout=10)

    return (
        f"AgntSpace installed as systemd service '{SERVICE_NAME}'.\n"
        f"  Auto-starts on boot, auto-restarts on crash.\n"
        f"  Manage: systemctl start/stop/restart/status {SERVICE_NAME}\n"
        f"  Logs: journalctl -u {SERVICE_NAME} -f"
    )


def _uninstall_linux() -> str:
    unit_path = Path(f"/etc/systemd/system/{SERVICE_NAME}.service")
    subprocess.run(["systemctl", "stop", SERVICE_NAME], capture_output=True, timeout=10)
    subprocess.run(["systemctl", "disable", SERVICE_NAME], capture_output=True, timeout=10)
    if unit_path.exists():
        unit_path.unlink()
    subprocess.run(["systemctl", "daemon-reload"], capture_output=True, timeout=10)
    return f"Service '{SERVICE_NAME}' removed."


# ── macOS (launchd) ──


def _install_macos(host: str, port: int) -> str:
    python = sys.executable
    label = f"com.archerfutura.{SERVICE_NAME}"
    plist = f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>{label}</string>
    <key>ProgramArguments</key>
    <array>
        <string>{python}</string>
        <string>-m</string>
        <string>agntspace.cli</string>
        <string>start</string>
        <string>--host</string>
        <string>{host}</string>
        <string>--port</string>
        <string>{port}</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>{Path.home()}/.agntspace/logs/service.log</string>
    <key>StandardErrorPath</key>
    <string>{Path.home()}/.agntspace/logs/service-error.log</string>
    <key>ThrottleInterval</key>
    <integer>5</integer>
</dict>
</plist>
"""
    plist_path = Path.home() / f"Library/LaunchAgents/{label}.plist"
    plist_path.parent.mkdir(parents=True, exist_ok=True)
    plist_path.write_text(plist)

    subprocess.run(["launchctl", "load", str(plist_path)], check=True, timeout=10)

    return (
        f"AgntSpace installed as launchd agent '{label}'.\n"
        f"  Auto-starts on login, auto-restarts on crash.\n"
        f"  Manage: launchctl start/stop {label}\n"
        f"  Logs: ~/.agntspace/logs/service.log"
    )


def _uninstall_macos() -> str:
    label = f"com.archerfutura.{SERVICE_NAME}"
    plist_path = Path.home() / f"Library/LaunchAgents/{label}.plist"

    subprocess.run(["launchctl", "unload", str(plist_path)], capture_output=True, timeout=10)
    if plist_path.exists():
        plist_path.unlink()
    return f"Agent '{label}' removed."
