#!/usr/bin/env bash
# 部署基线门禁（HEL-238）：候选提交必须包含当前线上提交的全部历史。
# 线上提交号从运行中的容器镜像 label 读取，禁止人工填写“看起来正确”的基线。
set -euo pipefail

HOST_DEFAULT="moxiaobai@192.168.200.11"
CONTAINER_DEFAULT="xiaobai-review"

usage() {
  cat <<'EOF'
用法: tools/check_deploy_baseline.sh <candidate_commit> [--live-revision <sha>]
  <candidate_commit>     准备构建/部署的提交（完整或前缀）
  --live-revision <sha>  仅测试用：直接指定线上提交，跳过 SSH 读取
环境变量:
  XB_BUILD_HOST          部署机 SSH（默认 moxiaobai@192.168.200.11）
  XB_LIVE_CONTAINER      运行中容器名（默认 xiaobai-review）
  XB_LIVE_REVISION       若已设置则视为线上提交，不再 SSH
EOF
  exit 2
}

[ $# -ge 1 ] || usage
CANDIDATE="$1"
shift
LIVE_OVERRIDE=""
while [ $# -gt 0 ]; do
  case "$1" in
    --live-revision)
      [ $# -ge 2 ] || usage
      LIVE_OVERRIDE="$2"
      shift 2
      ;;
    -h|--help)
      usage
      ;;
    *)
      echo "拒绝：未知参数 $1" >&2
      usage
      ;;
  esac
done

HOST="${XB_BUILD_HOST:-$HOST_DEFAULT}"
CONTAINER="${XB_LIVE_CONTAINER:-$CONTAINER_DEFAULT}"

case "$HOST" in
  *192.168.200.36*)
    echo "拒绝：192.168.200.36 已永久废弃，严禁在其上构建或部署。" >&2
    exit 1
    ;;
esac

cd "$(git rev-parse --show-toplevel)"

read_live_revision() {
  if [ -n "${LIVE_OVERRIDE}" ]; then
    printf '%s\n' "${LIVE_OVERRIDE}"
    return
  fi
  if [ -n "${XB_LIVE_REVISION:-}" ]; then
    printf '%s\n' "${XB_LIVE_REVISION}"
    return
  fi
  ssh -o BatchMode=yes "$HOST" bash -s -- "$CONTAINER" <<'REMOTE'
set -euo pipefail
container="$1"
revision="$(docker inspect --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' "$container" 2>/dev/null || true)"
if [ -z "$revision" ] || [ "$revision" = "<no value>" ]; then
  image="$(docker inspect --format '{{.Image}}' "$container" 2>/dev/null || true)"
  if [ -n "$image" ]; then
    revision="$(docker inspect --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' "$image" 2>/dev/null || true)"
  fi
fi
if [ -z "$revision" ] || [ "$revision" = "<no value>" ]; then
  echo "拒绝：无法从线上容器 ${container} 读取 org.opencontainers.image.revision。" >&2
  exit 1
fi
printf '%s\n' "$revision"
REMOTE
}

LIVE_RAW="$(read_live_revision)"
LIVE_RAW="$(printf '%s' "$LIVE_RAW" | tr -d '[:space:]')"
if [ -z "$LIVE_RAW" ]; then
  echo "拒绝：线上提交号为空，禁止继续构建或部署。" >&2
  exit 1
fi

CANDIDATE_SHA="$(git rev-parse --verify --quiet "${CANDIDATE}^{commit}" || true)"
if [ -z "$CANDIDATE_SHA" ]; then
  echo "拒绝：候选提交 ${CANDIDATE} 无法解析。" >&2
  exit 1
fi

LIVE_SHA="$(git rev-parse --verify --quiet "${LIVE_RAW}^{commit}" || true)"
if [ -z "$LIVE_SHA" ]; then
  echo "拒绝：线上提交 ${LIVE_RAW} 在本地仓库无法解析；请先 git fetch，禁止手工填写替代基线。" >&2
  exit 1
fi

echo "==> 部署基线对照"
echo "    线上提交: ${LIVE_SHA}"
echo "    候选提交: ${CANDIDATE_SHA}"

echo "==> 候选相对线上的文件差异"
DIFF_FILES="$(git diff --name-only "$LIVE_SHA" "$CANDIDATE_SHA" || true)"
if [ -z "$DIFF_FILES" ]; then
  echo "    （无文件差异）"
else
  printf '%s\n' "$DIFF_FILES" | sed 's/^/    /'
fi

echo "==> 候选将丢失的提交（线上有、候选没有）"
LOST="$(git log --oneline "$CANDIDATE_SHA".."$LIVE_SHA" || true)"
if [ -z "$LOST" ]; then
  echo "    （无）"
else
  printf '%s\n' "$LOST" | sed 's/^/    /'
fi

if ! git merge-base --is-ancestor "$LIVE_SHA" "$CANDIDATE_SHA"; then
  echo "拒绝：候选提交不是当前线上提交的后继，部署会丢失线上已有提交。禁止构建或部署。" >&2
  exit 1
fi

echo "==> 祖先关系通过：线上 ${LIVE_SHA:0:7} 是候选 ${CANDIDATE_SHA:0:7} 的祖先"
