#!/bin/bash
# ════════════════════════════════════════════════════════════════
# 光湖 · 开机自愈脚本 (Boot Heal)
# CVM 开机后自动拉起所有服务 + 检测 IP 变化
# ════════════════════════════════════════════════════════════════
#
# 部署方式: systemctl enable guanghulab-boot-heal
# 触发时机: 开机自动运行 (multi-user.target)
#
# 功能:
# 1. 检测当前公网 IP
# 2. 如果 IP 变了，写入警告日志（EIP 绑定后不应变）
# 3. 拉起 Forgejo、Nginx、Runner
# 4. 拉起 PM2 进程 (Wake Gate, Git Sync)
# 5. 检查 SSL 证书是否仍然有效
# 6. 输出健康报告
# ════════════════════════════════════════════════════════════════

set -e

LOG_FILE="/data/guanghulab/.runtime/boot-heal.log"
IP_RECORD="/data/guanghulab/.runtime/last-known-ip"

mkdir -p /data/guanghulab/.runtime

log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "═══════════════════════════════════════"
log "光湖 · 开机自愈启动"
log "═══════════════════════════════════════"

# ─── 1. 检测公网 IP ─────────────────────────────────────────
PUBLIC_IP=""
for api in "https://ifconfig.me" "https://api.ipify.org" "https://ipinfo.io/ip"; do
  PUBLIC_IP=$(curl -sf --connect-timeout 5 "$api" 2>/dev/null | tr -d '[:space:]')
  if [ -n "$PUBLIC_IP" ] && echo "$PUBLIC_IP" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then
    break
  fi
  PUBLIC_IP=""
done

if [ -n "$PUBLIC_IP" ]; then
  log "当前公网 IP: $PUBLIC_IP"

  # 与上次记录的 IP 对比
  if [ -f "$IP_RECORD" ]; then
    LAST_IP=$(cat "$IP_RECORD" | tr -d '[:space:]')
    if [ "$PUBLIC_IP" != "$LAST_IP" ]; then
      log "⚠️  IP 变化! 上次: $LAST_IP → 当前: $PUBLIC_IP"
      log "⚠️  请检查域名解析是否需要更新 (guanghulab.com 应指向 $PUBLIC_IP)"
    else
      log "✅ IP 未变化，域名无需更新"
    fi
  fi

  # 记录当前 IP
  echo "$PUBLIC_IP" > "$IP_RECORD"
else
  log "⚠️  无法检测公网 IP (网络可能未就绪)"
fi

# ─── 2. 等待网络就绪 ─────────────────────────────────────────
log "等待网络就绪..."
for i in $(seq 1 30); do
  if curl -sf --connect-timeout 2 http://metadata.tencentyun.com > /dev/null 2>&1; then
    log "✅ 网络就绪"
    break
  fi
  sleep 2
done

# ─── 3. 拉起系统服务 ─────────────────────────────────────────
log ""
log "▸ 拉起系统服务..."

# Forgejo
if systemctl is-active --quiet forgejo 2>/dev/null; then
  log "✅ Forgejo: 已运行"
else
  systemctl start forgejo 2>/dev/null && log "✅ Forgejo: 已启动" || log "❌ Forgejo: 启动失败"
fi

# Nginx
if systemctl is-active --quiet nginx 2>/dev/null; then
  log "✅ Nginx: 已运行"
else
  systemctl start nginx 2>/dev/null && log "✅ Nginx: 已启动" || log "❌ Nginx: 启动失败"
fi

# Gitea Runner
if systemctl is-active --quiet gitea-runner 2>/dev/null; then
  log "✅ Gitea Runner: 已运行"
else
  systemctl start gitea-runner 2>/dev/null && log "✅ Gitea Runner: 已启动" || log "❌ Gitea Runner: 启动失败"
fi

# ─── 4. 拉起 PM2 进程 ────────────────────────────────────────
log ""
log "▸ 拉起 PM2 进程..."

if command -v pm2 &>/dev/null; then
  pm2 resurrect 2>/dev/null && log "✅ PM2: 进程已恢复" || log "⚠️  PM2: 无保存的进程"

  # 等 3 秒让进程启动
  sleep 3

  # 逐个检查
  for proc in wake-gate guanghulab-git-sync guanghulab-mcp-server; do
    if pm2 describe "$proc" > /dev/null 2>&1; then
      STATUS=$(pm2 describe "$proc" 2>/dev/null | grep "status" | head -1 | awk '{print $4}')
      if [ "$STATUS" = "online" ]; then
        log "✅ $proc: 运行中"
      else
        pm2 restart "$proc" 2>/dev/null && log "✅ $proc: 已重启" || log "❌ $proc: 重启失败"
      fi
    else
      log "⚠️  $proc: PM2 中不存在，需要手动部署"
    fi
  done
else
  log "❌ PM2 未安装"
fi

# ─── 5. 检查 SSL 证书 ────────────────────────────────────────
log ""
log "▸ 检查 SSL 证书..."

if [ -f /etc/letsencrypt/live/guanghulab.com/fullchain.pem ]; then
  EXPIRY=$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/guanghulab.com/fullchain.pem 2>/dev/null | cut -d= -f2)
  if [ -n "$EXPIRY" ]; then
    EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null || echo 0)
    NOW_EPOCH=$(date +%s)
    DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
    if [ "$DAYS_LEFT" -gt 7 ]; then
      log "✅ SSL 证书有效，剩余 ${DAYS_LEFT} 天"
    else
      log "⚠️  SSL 证书即将过期! 剩余 ${DAYS_LEFT} 天，请运行 certbot renew"
    fi
  fi
else
  log "⚠️  SSL 证书文件不存在"
fi

# ─── 6. 健康报告 ─────────────────────────────────────────────
log ""
log "═══════════════════════════════════════"
log "开机自愈完成"

# 快速健康检查
ISSUES=0

# Forgejo
if ! curl -sf http://127.0.0.1:3001/ > /dev/null 2>&1; then
  log "❌ Forgejo 不可达"; ISSUES=$((ISSUES+1))
fi

# Nginx
if ! systemctl is-active --quiet nginx 2>/dev/null; then
  log "❌ Nginx 不可达"; ISSUES=$((ISSUES+1))
fi

# Wake Gate
if ! curl -sf http://127.0.0.1:8081/api/health > /dev/null 2>&1; then
  log "⚠️  Wake Gate 不可达"; ISSUES=$((ISSUES+1))
fi

# Git Sync
if ! curl -sf http://127.0.0.1:8082/health > /dev/null 2>&1; then
  log "⚠️  Git Sync 不可达"; ISSUES=$((ISSUES+1))
fi

# MCP Server
if ! curl -sf http://127.0.0.1:8083/health > /dev/null 2>&1; then
  log "⚠️  MCP Server 不可达"; ISSUES=$((ISSUES+1))
fi

if [ "$ISSUES" -eq 0 ]; then
  log "✅ 所有服务正常"
else
  log "⚠️  ${ISSUES} 个服务异常，需要人工介入"
fi

log "公网 IP: ${PUBLIC_IP:-未知}"
log "ICE-GL-ZY001 · TCS-0002∞"
log "═══════════════════════════════════════"
