#!/usr/bin/env bash
# 比对「主机上跑着的基础设施配置实物」与「本仓库里的副本」，检测 drift。
#
# 为什么需要它：这些配置文件此前只活在主机上，没有任何版本管理 —— 丢了就得靠人
# 回忆重建，改了也没人知道改过什么（INFRA-F89 修复时新增 gitea-proxy 暴露了这个
# 缺口，deploy-hook 的 server.py 是同一个毛病、尚未纳入，见 README）。
#
# 真源约定：**本仓库是真源，主机是部署产物**。若比对发现不一致，默认动作是
# 「查清主机为什么被直接改了，然后把改动回抄进仓库并 commit」，而不是拿仓库副本
# 去覆盖主机 —— 后者可能抹掉别人为救火做的紧急改动。
#
# 退出码（刻意三分，别合并）：
#   0 = 核过了，全部一致
#   1 = 核过了，有 drift            ← 真问题
#   2 = 没核到（连不上主机 / 文件读不到）← 不是"通过"，只是没验
# 把 2 和 0 合并会造出假绿：SSH 一坏就永远"通过"。
set -uo pipefail

HOST="${TVU_HOST:-nancy_zeng@172.239.57.41}"
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

# 清单：<仓库内相对路径>|<主机绝对路径>
PAIRS=(
  "infra/gitea-proxy/Caddyfile|/data/nancy_zeng/gitea-proxy/Caddyfile"
  "infra/gitea-proxy/docker-compose.yml|/data/nancy_zeng/gitea-proxy/docker-compose.yml"
)

if ! ssh -o BatchMode=yes -o ConnectTimeout=10 "$HOST" true 2>/dev/null; then
  echo "⚠️  连不上主机 $HOST —— 没有核对，这不等于通过。"
  echo "   （需要 SSH 才能比对；CI 里没有凭据，所以这个脚本不挂 CI，见 infra/README.md）"
  exit 2
fi

DRIFT=0
UNREAD=0
for pair in "${PAIRS[@]}"; do
  IFS='|' read -r local_rel remote_abs <<< "$pair"
  local_abs="$REPO_ROOT/$local_rel"

  if [ ! -f "$local_abs" ]; then
    echo "⚠️  仓库里缺文件：$local_rel"; UNREAD=1; continue
  fi
  if ! remote_content="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$HOST" "cat '$remote_abs'" 2>/dev/null)"; then
    echo "⚠️  主机上读不到：$remote_abs（文件没了？权限变了？）"; UNREAD=1; continue
  fi

  if diff -q <(printf '%s\n' "$remote_content") "$local_abs" >/dev/null 2>&1; then
    printf '✓ %s\n' "$local_rel"
  else
    printf '✗ DRIFT %s\n' "$local_rel"
    echo "   主机 $remote_abs 与仓库副本不一致，差异（左=主机，右=仓库）："
    diff <(printf '%s\n' "$remote_content") "$local_abs" | sed 's/^/     /'
    DRIFT=1
  fi
done

if [ "$DRIFT" = 1 ]; then
  echo
  echo "有 drift。先查清主机为什么被直接改了，再把改动回抄进仓库并 commit（别反向覆盖主机）。"
  exit 1
fi
if [ "$UNREAD" = 1 ]; then
  echo
  echo "有条目没核到 —— 这不等于通过。"
  exit 2
fi
echo
echo "全部一致（$((${#PAIRS[@]})) 个文件）。"
