"""Generic process manager.

Handles desktop-app launching, process killing via ``pkill``, and
bare ``subprocess.Popen`` calls for non-tmux/non-systemd tools.
"""

from __future__ import annotations

import shutil
import subprocess

# Terminal emulator candidates, ordered by preference.
_TERMINALS = [
    "xterm", "konsole", "gnome-terminal", "xfce4-terminal",
    "lxterminal", "alacritty", "kitty", "wezterm",
]


def detect_terminal() -> str:
    """Return the first available terminal emulator on the system."""
    for term in _TERMINALS:
        if shutil.which(term):
            return term
    return "xterm"


class ProcessManager:
    """Launch and terminate generic (desktop / CLI) processes."""

    def launch_desktop(self, command: str) -> None:
        """Fire-and-forget launch of a desktop command."""
        subprocess.Popen(command, shell=True)

    def launch_terminal(self, command: str, env: dict[str, str] | None = None) -> None:
        """Open *command* inside a new terminal emulator window."""
        term = detect_terminal()
        # xterm, alacritty, kitty, wezterm use -e; others use --
        sep = "-e" if term in ("xterm", "alacritty", "kitty", "wezterm") else "--"
        subprocess.Popen(
            f"{term} {sep} bash -c '{command}'",
            shell=True,
            env=env,
        )

    def kill_by_name(self, search_term: str) -> None:
        """Send SIGTERM to all processes matching *search_term*."""
        subprocess.run(
            f"pkill -f {search_term} 2>/dev/null", shell=True,
        )

    def docker_compose_down(self, compose_path: str, timeout: float = 10.0) -> None:
        """Run ``docker compose down`` on a given compose file."""
        subprocess.run(
            f"docker compose -f {compose_path} down",
            shell=True,
            timeout=timeout,
            capture_output=True,
        )
