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


def get_launchd_path() -> Path:
    if platform.system() != "Darwin":
        raise RuntimeError("launchd is only available on macOS")

    if not shutil.which("launchctl"):
        raise RuntimeError("launchctl command not found")

    user_agents = Path.home() / "Library" / "LaunchAgents"
    if not user_agents.exists():
        raise RuntimeError(f"LaunchAgents directory not found at {user_agents}")

    return user_agents / "com.toolbox.daemon.plist"


def get_toolbox_dir() -> Path:
    """Get the standard toolbox directory (~/.toolbox)"""
    toolbox_dir = Path.home() / ".toolbox"
    toolbox_dir.mkdir(parents=True, exist_ok=True)
    return toolbox_dir


def get_launch_script_path() -> Path:
    """Get the path to the launch daemon script"""
    return get_toolbox_dir() / "launch_daemon.sh"


user = os.environ["USER"]

LAUNCH_SCRIPT_TEMPLATE = """#!/bin/bash
# Toolbox daemon launch script
# This script is auto-generated by toolbox

# Add common UV paths to PATH
export PATH="/opt/homebrew/bin:/usr/local/bin:$HOME/.local/bin:$HOME/.cargo/bin:$PATH"

exec "{python_executable}" -m toolbox.cli.cli daemon run-foreground
"""

LAUNCHD_PLIST_TEMPLATE = """<?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.toolbox.daemon</string>
    <key>ProgramArguments</key>
    <array>
        <string>{script_path}</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/tmp/toolbox-daemon.out</string>
    <key>StandardErrorPath</key>
    <string>/tmp/toolbox-daemon.err</string>
</dict>
</plist>"""


def create_launch_script() -> Path:
    """Create the launch daemon script with the current Python executable"""
    script_path = get_launch_script_path()
    python_executable = sys.executable

    script_content = LAUNCH_SCRIPT_TEMPLATE.format(python_executable=python_executable)

    script_path.write_text(script_content)
    script_path.chmod(0o755)  # Make executable
    return script_path


def get_launchd_plist() -> str:
    """Generate the launchd plist content with the current launch script path"""
    script_path = get_launch_script_path()

    return LAUNCHD_PLIST_TEMPLATE.format(script_path=script_path)


def add_to_launchd() -> Path:
    """Add toolbox daemon to launchd for automatic startup.

    Returns:
        Path: The path to the created plist file

    Raises:
        RuntimeError: If launchd is not available or setup fails
    """
    # Create the launch script first
    create_launch_script()

    # Create and load the plist
    plist_path = get_launchd_path()
    plist_content = get_launchd_plist()
    plist_path.write_text(plist_content)
    subprocess.run(["launchctl", "load", str(plist_path)])
    return plist_path


def is_daemon_installed() -> bool:
    """Check if the toolbox daemon is installed in launchd.

    Returns:
        bool: True if daemon is installed, False otherwise
    """
    try:
        plist_path = get_launchd_path()
        return plist_path.exists()
    except RuntimeError:
        # If launchd is not available (non-macOS), consider it not installed
        return False


def remove_from_launchd() -> Path:
    """Remove toolbox daemon from launchd.

    Returns:
        Path: The path to the removed plist file

    Raises:
        RuntimeError: If launchd is not available
    """
    plist_path = get_launchd_path()
    subprocess.run(["launchctl", "unload", str(plist_path)])
    plist_path.unlink(missing_ok=True)

    # Optionally clean up the launch script
    script_path = get_launch_script_path()
    script_path.unlink(missing_ok=True)

    return plist_path
