#!/usr/bin/env bash
# 后续更新：可选拉代码/加载镜像，备份数据，构建或使用新镜像，执行迁移并滚动到新容器。

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/deploy-lib.sh
source "$SCRIPT_DIR/deploy-lib.sh"

PULL_CODE=false
NO_BUILD=false
SKIP_BACKUP=false
ALLOW_DEFAULT_SECRETS=false
IMAGE_TAR=""

usage() {
  cat <<'EOF'
用法: scripts/deploy-update.sh [选项]

默认流程：
  1. 检查 .env.docker
  2. 启动并等待 postgres / redis
  3. 备份 PostgreSQL 与 uploads 到 ./backups
  4. 构建 api / player / admin 镜像
  5. 使用新 api 镜像执行 prisma migrate deploy
  6. 启动/替换 api、player、admin 容器
  7. 检查 prisma migrate status

选项:
  --pull                  先执行 git pull --ff-only
  --images PATH           先 docker load 指定镜像 tar，并自动跳过本机构建
  --tag TAG               使用指定镜像 tag，并写入 .env.docker 的 IMAGE_TAG
  --no-build              不构建镜像，直接使用服务器已有镜像
  --no-backup             跳过 PostgreSQL 与 uploads 备份
  --allow-default-secrets 允许 .env.docker 使用示例密钥，仅测试环境使用
  -h, --help              显示帮助

示例:
  ./scripts/deploy-update.sh --pull
  ./scripts/deploy-update.sh --images thebet365-images-v1.2.3.tar --tag v1.2.3
  ./scripts/deploy-update.sh --no-build
EOF
}

while [ $# -gt 0 ]; do
  case "$1" in
    --pull)
      PULL_CODE=true
      shift
      ;;
    --images)
      IMAGE_TAR="${2:?缺少 --images 参数值}"
      NO_BUILD=true
      shift 2
      ;;
    --tag)
      set_deploy_image_tag "${2:?缺少 --tag 参数值}"
      shift 2
      ;;
    --no-build)
      NO_BUILD=true
      shift
      ;;
    --no-backup)
      SKIP_BACKUP=true
      shift
      ;;
    --allow-default-secrets)
      ALLOW_DEFAULT_SECRETS=true
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      die "未知参数: $1"
      ;;
  esac
done

cd "$ROOT"
require_docker
ensure_env_file || exit 1
validate_prod_env "$ALLOW_DEFAULT_SECRETS"

if [ -n "$IMAGE_TAR" ] && [ -z "${DEPLOY_IMAGE_TAG:-}" ]; then
  inferred_tag="$(infer_image_tag_from_tar "$IMAGE_TAR")"
  if [ -n "$inferred_tag" ]; then
    set_deploy_image_tag "$inferred_tag"
    log "从镜像包文件名推断 tag: $inferred_tag"
  fi
fi

if [ "$PULL_CODE" = true ]; then
  require_command git
  log "拉取代码: git pull --ff-only"
  git pull --ff-only
fi

if [ -n "$IMAGE_TAR" ]; then
  load_image_tar "$IMAGE_TAR"
fi

start_infra

if [ "$SKIP_BACKUP" = false ]; then
  backup_database "pre-update"
  backup_uploads "pre-update"
  prune_old_backups
else
  warn "已跳过 PostgreSQL 与 uploads 备份"
fi

if [ "$NO_BUILD" = false ]; then
  build_app_images
else
  log "跳过镜像构建，使用服务器已有镜像"
  require_images_for_current_tag
fi

run_prisma_migrations

log "启动/更新 api / player / admin"
compose up -d api player admin
wait_for_stack_ready
show_prisma_status
compose ps
persist_image_tag
record_release_state "update"
print_stack_urls
