"""
Doit Agent - OS Service Integration
Auto-start configuration for Linux (systemd), macOS (LaunchAgent), Windows (Task Scheduler/Service).
"""
from __future__ import annotations

import logging
import os
import subprocess
import sys
from pathlib import Path

logger = logging.getLogger("doit.services")

# Find the doit executable
def _find_doit_exe() -> str:
    import shutil
    # Try which/where
    exe = shutil.which("doit")
    if exe:
        return exe
    # Fallback: use current python + module
    python = sys.executable
    return f"{python} -m cli.main"


# ── Linux: systemd user service ───────────────────────────────────────────────

SYSTEMD_UNIT = """\
[Unit]
Description=Doit - Telegram Automation Agent
After=network.target

[Service]
Type=simple
ExecStart={exe} run
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=default.target
"""


def install_systemd() -> tuple[bool, str]:
    """Install doit as a systemd user service."""
    service_dir = Path.home() / ".config" / "systemd" / "user"
    service_dir.mkdir(parents=True, exist_ok=True)
    service_file = service_dir / "doit.service"

    exe = _find_doit_exe()
    content = SYSTEMD_UNIT.format(exe=exe)
    service_file.write_text(content)

    try:
        subprocess.run(["systemctl", "--user", "daemon-reload"], check=True, capture_output=True)
        subprocess.run(["systemctl", "--user", "enable", "doit"], check=True, capture_output=True)
        subprocess.run(["systemctl", "--user", "start", "doit"], check=False, capture_output=True)
        return True, f"systemd user service installed: {service_file}"
    except subprocess.CalledProcessError as e:
        return False, f"systemd error: {e.stderr.decode() if e.stderr else e}"
    except FileNotFoundError:
        return False, "systemctl not found. Is systemd running?"


def uninstall_systemd() -> tuple[bool, str]:
    try:
        subprocess.run(["systemctl", "--user", "stop", "doit"], capture_output=True)
        subprocess.run(["systemctl", "--user", "disable", "doit"], capture_output=True)
        service_file = Path.home() / ".config" / "systemd" / "user" / "doit.service"
        service_file.unlink(missing_ok=True)
        subprocess.run(["systemctl", "--user", "daemon-reload"], capture_output=True)
        return True, "systemd service removed"
    except Exception as e:
        return False, str(e)


# ── macOS: LaunchAgent ────────────────────────────────────────────────────────

LAUNCHAGENT_PLIST = """\
<?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>com.doit.agent</string>
    <key>ProgramArguments</key>
    <array>
        {exe_args}
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>{log_dir}/stdout.log</string>
    <key>StandardErrorPath</key>
    <string>{log_dir}/stderr.log</string>
    <key>EnvironmentVariables</key>
    <dict>
        <key>PYTHONUNBUFFERED</key>
        <string>1</string>
    </dict>
</dict>
</plist>
"""


def install_launchagent() -> tuple[bool, str]:
    """Install doit as a macOS LaunchAgent."""
    from core.config import LOG_DIR
    launch_dir = Path.home() / "Library" / "LaunchAgents"
    launch_dir.mkdir(parents=True, exist_ok=True)
    plist_file = launch_dir / "com.doit.agent.plist"

    exe = _find_doit_exe()
    # Build XML array of args
    parts = exe.split()
    parts.append("run")
    exe_args = "\n        ".join(f"<string>{p}</string>" for p in parts)

    content = LAUNCHAGENT_PLIST.format(exe_args=exe_args, log_dir=LOG_DIR)
    plist_file.write_text(content)

    try:
        # Unload first (in case it exists)
        subprocess.run(["launchctl", "unload", str(plist_file)], capture_output=True)
        result = subprocess.run(
            ["launchctl", "load", "-w", str(plist_file)],
            capture_output=True, text=True
        )
        if result.returncode != 0:
            return False, f"launchctl error: {result.stderr}"
        return True, f"LaunchAgent installed: {plist_file}"
    except FileNotFoundError:
        return False, "launchctl not found"
    except Exception as e:
        return False, str(e)


def uninstall_launchagent() -> tuple[bool, str]:
    plist_file = Path.home() / "Library" / "LaunchAgents" / "com.doit.agent.plist"
    try:
        subprocess.run(["launchctl", "unload", str(plist_file)], capture_output=True)
        plist_file.unlink(missing_ok=True)
        return True, "LaunchAgent removed"
    except Exception as e:
        return False, str(e)


# ── Windows: Task Scheduler ───────────────────────────────────────────────────

def install_windows_task() -> tuple[bool, str]:
    """Install doit via Windows Task Scheduler (auto-start on login)."""
    exe = _find_doit_exe()
    task_name = "DoitAgent"
    try:
        cmd = [
            "schtasks", "/create", "/f",
            "/tn", task_name,
            "/sc", "ONLOGON",
            "/tr", f'"{exe} run"',
            "/rl", "HIGHEST",
            "/ru", os.environ.get("USERNAME", ""),
        ]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode != 0:
            return False, f"schtasks error: {result.stderr}"
        # Start immediately
        subprocess.run(["schtasks", "/run", "/tn", task_name], capture_output=True)
        return True, f"Windows task scheduler entry created: {task_name}"
    except Exception as e:
        return False, str(e)


def uninstall_windows_task() -> tuple[bool, str]:
    try:
        subprocess.run(["schtasks", "/delete", "/f", "/tn", "DoitAgent"], capture_output=True)
        return True, "Windows task removed"
    except Exception as e:
        return False, str(e)


# ── Dispatch ──────────────────────────────────────────────────────────────────

def install_service() -> tuple[bool, str]:
    """Install auto-start service for the current OS."""
    if sys.platform == "linux":
        return install_systemd()
    elif sys.platform == "darwin":
        return install_launchagent()
    elif sys.platform == "win32":
        return install_windows_task()
    else:
        return False, f"Unsupported OS: {sys.platform}"


def uninstall_service() -> tuple[bool, str]:
    if sys.platform == "linux":
        return uninstall_systemd()
    elif sys.platform == "darwin":
        return uninstall_launchagent()
    elif sys.platform == "win32":
        return uninstall_windows_task()
    else:
        return False, f"Unsupported OS: {sys.platform}"


def service_status() -> tuple[bool, str]:
    """Check if the doit service is installed and running."""
    if sys.platform == "linux":
        result = subprocess.run(
            ["systemctl", "--user", "is-active", "doit"],
            capture_output=True, text=True
        )
        active = result.stdout.strip() == "active"
        return active, result.stdout.strip()
    elif sys.platform == "darwin":
        plist = Path.home() / "Library" / "LaunchAgents" / "com.doit.agent.plist"
        installed = plist.exists()
        return installed, "installed" if installed else "not installed"
    elif sys.platform == "win32":
        result = subprocess.run(
            ["schtasks", "/query", "/tn", "DoitAgent", "/fo", "LIST"],
            capture_output=True, text=True
        )
        active = result.returncode == 0
        return active, "running" if active else "not found"
    return False, "unknown"
