#!/usr/bin/env bash
# 全量代码门禁：部署前在本地开发机执行，确保后端 + 前端检查全绿。
#
# 用途：
#   - 部署门禁：scripts/deploy-prod.sh 在 build 镜像前自动调用本脚本（--skip-check 可跳过）
#   - 手动校验：开发时手动跑 ./scripts/check.sh
#
# 包含：
#   后端：go vet + go build + go test
#   前端：npm run check (prettier + eslint + typecheck) + npm run test + npm run build
#
# 任一步骤失败即退出非零，阻止部署。
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BACKEND_DIR="${ROOT_DIR}/backend"
FRONTEND_DIR="${ROOT_DIR}/frontend"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
NC='\033[0m'

log()      { printf "${BLUE}[check]${NC} %s\n" "$*"; }
log_ok()    { printf "${GREEN}[check]${NC} %s\n" "$*"; }
log_warn()  { printf "${YELLOW}[check]${NC} %s\n" "$*"; }
log_error() { printf "${RED}[check]${NC} %s\n" "$*" >&2; }

SKIP_BACKEND=0
SKIP_FRONTEND=0
SKIP_TESTS=0

show_help() {
  cat << EOF
用法: ./scripts/check.sh [选项]

全量代码门禁：后端 go vet/build/test + 前端 check/test/build。

选项:
  --skip-backend     跳过后端检查
  --skip-frontend    跳过前端检查
  --skip-tests       跳过测试（仅做 vet/build + lint/typecheck/build）
  -h, --help         显示帮助

示例:
  ./scripts/check.sh
  ./scripts/check.sh --skip-frontend
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --skip-backend)  SKIP_BACKEND=1;  shift ;;
    --skip-frontend) SKIP_FRONTEND=1; shift ;;
    --skip-tests)    SKIP_TESTS=1;    shift ;;
    -h|--help)       show_help; exit 0 ;;
    *)
      log_error "未知参数: $1"
      show_help
      exit 1
      ;;
  esac
done

step_start() { printf "\n${BLUE}[check]${NC} \033[1m▶ %s${NC}\n" "$1"; }
step_ok()    { log_ok "✓ $1 ($2)"; }
step_fail()  { log_error "✗ $1 失败"; }

run_step() {
  # run_step "步骤名" 命令...
  local name="$1"; shift
  local start
  start=$(date +%s)
  step_start "$name"
  if "$@"; then
    local elapsed=$(( $(date +%s) - start ))
    step_ok "$name" "${elapsed}s"
  else
    step_fail "$name"
    return 1
  fi
}

FAILED=0

# ---------------------------------------------------------------------------
# 后端检查
# ---------------------------------------------------------------------------
if [[ "${SKIP_BACKEND}" == "0" ]]; then
  log "后端检查目录: ${BACKEND_DIR}"
  cd "${BACKEND_DIR}"

  run_step "go vet ./..."      go vet ./...     || FAILED=1
  run_step "go build ./..."    go build ./...   || FAILED=1
  if [[ "${SKIP_TESTS}" == "0" ]]; then
    # -p 1 串行避免 SQLite 内存库并发; 真实 MySQL e2e 默认 skip
    run_step "go test ./..."   go test -p 1 -count=1 ./... || FAILED=1
  else
    log_warn "跳过后端测试 (--skip-tests)"
  fi
else
  log_warn "跳过后端检查 (--skip-backend)"
fi

# ---------------------------------------------------------------------------
# 前端检查
# ---------------------------------------------------------------------------
if [[ "${SKIP_FRONTEND}" == "0" ]]; then
  log "前端检查目录: ${FRONTEND_DIR}"
  cd "${FRONTEND_DIR}"

  if [[ ! -d node_modules ]]; then
    run_step "npm ci (首次安装依赖)" npm ci || FAILED=1
  fi

  # npm run check = prettier --check + eslint --max-warnings=0 + vue-tsc
  run_step "npm run check (prettier + eslint + typecheck)" npm run check || FAILED=1
  if [[ "${SKIP_TESTS}" == "0" ]]; then
    run_step "npm run test (vitest)" npm run test || FAILED=1
  else
    log_warn "跳过前端测试 (--skip-tests)"
  fi
  run_step "npm run build (vite 生产构建)"                 npm run build || FAILED=1
else
  log_warn "跳过前端检查 (--skip-frontend)"
fi

# ---------------------------------------------------------------------------
# 汇总
# ---------------------------------------------------------------------------
printf "\n"
if [[ "${FAILED}" == "0" ]]; then
  log_ok "全部检查通过 ✓"
  exit 0
else
  log_error "检查未通过，已阻止本次部署。可用 --skip-check 强制跳过（不推荐）。"
  exit 1
fi
