#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Capture daemon health check — ensures agent's capture daemon is alive before launch."""
from __future__ import annotations

import json
import subprocess
import sys
from pathlib import Path

ROOT_DIR = Path(__file__).resolve().parent.parent.parent
STATE_DIR = ROOT_DIR / "state"
DAEMON_PIDS_FILE = STATE_DIR / "daemon_pids.json"

_AGENT_DAEMON_SCRIPT = {
    "claude": ROOT_DIR / "pulse" / "agents" / "pulse_claude.py",
    "gemini": ROOT_DIR / "pulse" / "agents" / "pulse_gemini.py",
    "codex": ROOT_DIR / "pulse" / "agents" / "pulse_codex.py",
    "grok": ROOT_DIR / "pulse" / "agents" / "pulse_grok.py",
}


def _is_pid_alive(pid: int) -> bool:
    """Check if a PID is alive (cross-platform)."""
    import os
    if os.name == "nt":
        try:
            out = subprocess.check_output(
                ["tasklist", "/FI", f"PID eq {pid}"],
                stderr=subprocess.DEVNULL, creationflags=0x08000000,
            ).decode()
            return str(pid) in out
        except Exception:
            return False
    try:
        import os as _os
        _os.kill(pid, 0)
        return True
    except OSError:
        return False


def _ensure_capture_daemon(agent_name: str) -> None:
    """Verify the agent's capture daemon is alive; restart if dead.

    Reads daemon_pids.json, checks PID liveness, spawns a new daemon if needed.
    """
    agent_key = agent_name.replace("_daemon", "").lower()
    script = _AGENT_DAEMON_SCRIPT.get(agent_key)
    if not script or not script.exists():
        return

    # Check existing PID
    daemon_id = f"{agent_key}_daemon"
    try:
        pids_data = json.loads(DAEMON_PIDS_FILE.read_text(encoding="utf-8")) if DAEMON_PIDS_FILE.exists() else []
    except Exception:
        pids_data = []

    # daemon_pids.json is a list of PIDs (integers) — check if any capture daemon is alive
    # The orchestrator manages all daemons; we only need to spawn if orchestrator isn't running
    from pulse.tasks.task_ops import is_orchestrator_running
    if is_orchestrator_running():
        return  # Orchestrator handles daemon lifecycle

    # Orchestrator not running — spawn capture daemon directly
    try:
        proc = subprocess.Popen(
            [sys.executable, str(script)],
            stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
            creationflags=0x08000000 if sys.platform == "win32" else 0,
        )
        sys.stderr.write(f"[PULSE] Started capture daemon for {agent_key} (PID {proc.pid})\n")
    except Exception as e:
        sys.stderr.write(f"[PULSE] Failed to start capture daemon for {agent_key}: {e}\n")
