#!/usr/bin/env bash
# Docker Desktop 引擎假死自愈（macOS）
# 场景：com.docker.backend 在跑，但 Linux 引擎无响应 → 无鲸鱼 / 打不开界面 / docker 报 500
# 策略：仅当「后端进程存在 && docker info 在时限内失败」时执行 docker desktop restart，避免用户完全退出 Docker 时被误拉起。
#
# 用法：
#   bash sdk/scripts/docker_engine_guard.sh           # 检查一次，必要时修复
#   bash sdk/scripts/docker_engine_guard.sh --dry-run # 只打印将执行的操作，不重启
#   bash sdk/scripts/docker_engine_guard.sh --open-ui # 修复后尝试打开仪表盘（适合手动排障）

set -uo pipefail

# launchd 默认 PATH 极窄，需显式加入 Docker CLI 常见路径
export PATH="/opt/homebrew/bin:/usr/local/bin:${HOME}/.docker/bin:/usr/bin:/bin:/usr/sbin:/sbin:${PATH:-}"

DRY_RUN=false
OPEN_UI=false
for arg in "$@"; do
  case "$arg" in
    --dry-run) DRY_RUN=true ;;
    --open-ui) OPEN_UI=true ;;
  esac
done

if [[ "$(uname -s)" != "Darwin" ]]; then
  exit 0
fi

if [[ ! -d "/Applications/Docker.app" ]]; then
  exit 0
fi

if ! command -v docker >/dev/null 2>&1; then
  exit 0
fi

log_line() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}

# 后端未运行：视为用户未开 Docker，不处理
if ! pgrep -f "com.docker.backend" >/dev/null 2>&1; then
  log_line "skip: com.docker.backend 未运行"
  exit 0
fi

# 限时探测 docker info（避免 launchd 任务挂死，最多约 15s）
info_ok=false
docker info >/dev/null 2>&1 &
dp=$!
for _ in $(seq 1 15); do
  if ! kill -0 "$dp" 2>/dev/null; then
    if wait "$dp"; then info_ok=true; fi
    break
  fi
  sleep 1
done
if kill -0 "$dp" 2>/dev/null; then
  kill -9 "$dp" 2>/dev/null || true
  wait "$dp" 2>/dev/null || true
fi

if [[ "$info_ok" == true ]]; then
  log_line "ok: docker info 正常"
  exit 0
fi

log_line "bad: docker info 失败但后端在跑 → 判定引擎假死"

if [[ "$DRY_RUN" == true ]]; then
  log_line "dry-run: 将执行 docker desktop restart"
  exit 2
fi

if docker desktop restart 2>&1; then
  log_line "done: docker desktop restart 已执行，等待引擎…"
else
  log_line "warn: docker desktop restart 返回非 0"
fi

for _ in $(seq 1 60); do
  if docker info >/dev/null 2>&1; then
    log_line "ok: 引擎已恢复"
    if [[ "$OPEN_UI" == true ]]; then
      open "/Applications/Docker.app/Contents/MacOS/Docker Desktop.app" 2>/dev/null || open -a Docker
      sleep 1
      open "docker-desktop://dashboard" 2>/dev/null || true
      log_line "open-ui: 已尝试打开仪表盘"
    fi
    exit 0
  fi
  sleep 2
done

log_line "fail: 重启后 docker info 仍失败，请人工：升级 Docker Desktop 或 Troubleshoot → Reset"
exit 1
