#!/usr/bin/env bash
# 小白复盘唯一安全构建入口（HEL-235 固化）
# 方式：从明确 Git 提交 git archive 流式传输到部署机 docker build，不使用任何服务器工作树。
# 铁律：禁止在服务器目录（如 /opt/1panel/docker/compose/xiaobaifupan）里 docker build；
#       禁止构建 latest 等不带提交短号的 tag；严禁向 192.168.200.36 构建或部署。
set -euo pipefail

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

usage() {
  cat <<'EOF'
用法: tools/build_image.sh <commit> <tag>
  <commit>  提交号（完整或前缀），必须能被 origin 解析；构建前会自动 fetch
  <tag>     镜像 tag，必须以 -<提交短号7位> 结尾，锁定镜像来源；禁止 latest、rollback-*
示例: tools/build_image.sh cefc86917d89 verify-hel235-cefc869
说明: 仅构建镜像，不启动、不替换任何容器；换版与回滚另行人工执行。
EOF
  exit 2
}

[ $# -eq 2 ] || usage
COMMIT="$1"
TAG="$2"
HOST="${XB_BUILD_HOST:-$HOST_DEFAULT}"

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

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

echo "==> 同步远端引用"
git fetch origin --prune --quiet

FULL_SHA="$(git rev-parse --verify --quiet "${COMMIT}^{commit}" || true)"
if [ -z "$FULL_SHA" ]; then
  echo "拒绝：提交 ${COMMIT} 无法解析。构建源必须锁定到已推送 origin 的明确提交。" >&2
  exit 1
fi
SHORT="${FULL_SHA:0:7}"
SUBJECT="$(git log -1 --format=%s "$FULL_SHA")"

case "$TAG" in
  latest)
    echo "拒绝：禁止构建 latest，模糊 tag 无法追溯来源提交。" >&2
    exit 1
    ;;
  rollback-*)
    echo "拒绝：rollback-* 是部署时对既有镜像的人工 docker tag，不允许用来构建。" >&2
    exit 1
    ;;
esac
if [[ "$TAG" != *-"$SHORT" ]]; then
  echo "拒绝：tag「${TAG}」必须以 -${SHORT} 结尾，保证镜像 tag 与来源提交一一对应。" >&2
  exit 1
fi

echo "==> 部署基线门禁（线上提交必须是候选祖先）"
bash "$(git rev-parse --show-toplevel)/tools/check_deploy_baseline.sh" "$FULL_SHA"

echo "==> 构建计划"
echo "    提交: ${FULL_SHA}  ${SUBJECT}"
echo "    镜像: ${REPO_NAME}:${TAG}  @ ${HOST}"
echo "    方式: git archive 流式构建（不读取服务器上任何代码目录）"

echo "==> 流式构建开始"
git archive --format=tar "$FULL_SHA" \
  | ssh -o BatchMode=yes "$HOST" docker build --rm \
      -t "${REPO_NAME}:${TAG}" \
      --label "org.opencontainers.image.revision=${FULL_SHA}" \
      --label "org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
      --label "org.opencontainers.image.source=git-archive-stream" \
      -

echo "==> 回读校验镜像内记录的提交号"
GOT="$(ssh -o BatchMode=yes "$HOST" "docker image inspect ${REPO_NAME}:${TAG} --format '{{index .Config.Labels \"org.opencontainers.image.revision\"}}'" 2>/dev/null || true)"
if [ "$GOT" != "$FULL_SHA" ]; then
  echo "校验失败：镜像 revision='${GOT:-<空>}'，期望 ${FULL_SHA}。删除不可信镜像，中止。" >&2
  ssh -o BatchMode=yes "$HOST" docker rmi "${REPO_NAME}:${TAG}" >/dev/null 2>&1 || true
  exit 1
fi

IMAGE_ID="$(ssh -o BatchMode=yes "$HOST" "docker image inspect ${REPO_NAME}:${TAG} --format '{{.Id}}'")"
SHORT_ID="${IMAGE_ID##*:}"

ssh -o BatchMode=yes "$HOST" \
  "mkdir -p ~/xiaobai-build && printf '%s\t%s\t%s\t%s\tgit-archive-stream\n' \"\$(date '+%F %T')\" ${REPO_NAME}:${TAG} ${FULL_SHA} ${SHORT_ID} >> ~/xiaobai-build/BUILD_LOG.tsv"

echo "==> 完成"
echo "    ${REPO_NAME}:${TAG}  (${SHORT_ID})"
echo "    来源提交 ${FULL_SHA} 已写入镜像 label 与 ~/xiaobai-build/BUILD_LOG.tsv"
