#!/usr/bin/env bash
# 清理 Isaac 真实仿真闭环测试遗留进程。
#
# 默认只列出候选进程，不会停止任何东西。
# 使用 --kill 后才会发送 SIGINT/SIGTERM。

set -Eeuo pipefail

DO_KILL=0

usage() {
  cat <<'EOF'
用法:
  ./stop_isaac_real_sim_stack.sh [选项]

选项:
  --list        只列出候选进程，默认行为。
  --kill        停止候选进程，先 SIGINT，未退出再 SIGTERM。
  -h, --help    显示帮助。

说明:
  该脚本只匹配 AutoCalib-Workshop 仿真闭环相关进程，例如:
  launch_sim_stack.py、minimal_workshop_demo.launch.py、
  workshop_orchestrator_v2_node、vehicle_agent_gateway_node 等。
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --list)
      DO_KILL=0
      shift
      ;;
    --kill)
      DO_KILL=1
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "[ERROR] 未知参数: $1" >&2
      exit 1
      ;;
  esac
done

PATTERNS=(
  "src/simulation/tools/launch_sim_stack.py --component isaac"
  "src/simulation/tools/launch_sim_stack.py --component vehicle-agent"
  "src/simulation/tools/launch_sim_stack.py --component sensor-agent"
  "src/simulation/tools/launch_sim_stack.py --component wifi6-gateway"
  "src/simulation/tools/launch_sim_stack.py --component external-pose-bridge"
  "src/simulation/tools/launch_sim_stack.py --component sensor-ingest"
  "minimal_workshop_demo.launch.py"
  "build_calibration_room.py"
  "isaac_vehicle_unified_agent_sim.py"
  "isaac_vehicle_agent_sim.py"
  "isaac_vehicle_sensor_agent_sim.py"
  "vehicle_wifi6_gateway_sim.py"
  "external_pose_wifi6_bridge_sim.py"
  "workshop_sensor_ingest_sim.py"
  "workshop_orchestrator_v2_node"
  "vehicle_profile_manager_node"
  "external_localization_service_node"
  "sensor_calibration_service_node"
  "chassis_calibration_service_node"
  "control_calibration_service_node"
  "vehicle_agent_gateway_node"
)

declare -A PID_TO_CMD=()

for pattern in "${PATTERNS[@]}"; do
  while IFS= read -r line; do
    [[ -n "${line}" ]] || continue
    pid="${line%% *}"
    cmd="${line#* }"
    [[ "${pid}" != "$$" ]] || continue
    PID_TO_CMD["${pid}"]="${cmd}"
  done < <(pgrep -af -- "${pattern}" 2>/dev/null || true)
done

if [[ "${#PID_TO_CMD[@]}" -eq 0 ]]; then
  echo "[INFO] 未发现 AutoCalib 仿真闭环相关遗留进程。"
  exit 0
fi

echo "[INFO] 发现候选进程:"
for pid in "${!PID_TO_CMD[@]}"; do
  echo "  pid=${pid}  ${PID_TO_CMD[${pid}]}"
done | sort -n -k1.7

if [[ "${DO_KILL}" -eq 0 ]]; then
  echo "[INFO] 当前是只读检查。确认无误后可执行: ./stop_isaac_real_sim_stack.sh --kill"
  exit 0
fi

echo "[INFO] 发送 SIGINT..."
for pid in "${!PID_TO_CMD[@]}"; do
  kill -INT "${pid}" >/dev/null 2>&1 || true
done

sleep 3

echo "[INFO] 检查未退出进程并发送 SIGTERM..."
for pid in "${!PID_TO_CMD[@]}"; do
  if kill -0 "${pid}" >/dev/null 2>&1; then
    echo "  SIGTERM pid=${pid}"
    kill -TERM "${pid}" >/dev/null 2>&1 || true
  fi
done

sleep 1

LEFT=0
for pid in "${!PID_TO_CMD[@]}"; do
  if kill -0 "${pid}" >/dev/null 2>&1; then
    echo "[WARN] 进程仍未退出: pid=${pid} ${PID_TO_CMD[${pid}]}" >&2
    LEFT=1
  fi
done

if [[ "${LEFT}" -eq 0 ]]; then
  echo "[INFO] 清理完成。"
else
  echo "[WARN] 仍有进程未退出，请手动确认后再处理。" >&2
fi
