#!/usr/bin/env bash
# datahub 更新脚本：git pull + 智能重建 + 滚动重启
#
# 用法：bash update.sh [选项]
#   --force-rebuild   不看 git diff，强制重建所有镜像
#   --skip-migrate    检测到新迁移时不提示，直接跳过

set -euo pipefail

B='\033[34m'; G='\033[32m'; Y='\033[33m'; R='\033[31m'; N='\033[0m'
step() { echo -e "\n${B}=> $*${N}"; }
ok()   { echo -e "${G}[OK]${N} $*"; }
warn() { echo -e "${Y}[!]${N} $*"; }
err()  { echo -e "${R}[ERR]${N} $*" >&2; }

FORCE_REBUILD=false
SKIP_MIGRATE=false
for arg in "$@"; do
    case "$arg" in
        --force-rebuild) FORCE_REBUILD=true ;;
        --skip-migrate)  SKIP_MIGRATE=true ;;
        -h|--help)
            sed -n '2,7p' "$0"
            exit 0
            ;;
        *) echo "未知参数: $arg" >&2; exit 1 ;;
    esac
done

SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
REPO_ROOT=$(cd "$SCRIPT_DIR/../../.." && pwd)
QUADLET_DIR="$HOME/.config/containers/systemd"

cd "$REPO_ROOT"

# 1. 必须是 git 仓库且工作区干净
if [ ! -d .git ]; then
    err "$REPO_ROOT 不是 git 仓库"
    exit 1
fi
if ! git diff --quiet || ! git diff --cached --quiet; then
    err "工作区有未提交的变更，先 stash 或 commit"
    git status --short
    exit 1
fi

# 2. git pull
step "git pull"
OLD_HEAD=$(git rev-parse HEAD)
git pull --ff-only
NEW_HEAD=$(git rev-parse HEAD)

if [ "$OLD_HEAD" = "$NEW_HEAD" ] && [ "$FORCE_REBUILD" = false ]; then
    ok "代码已是最新，无需更新（如需强制重建请加 --force-rebuild）"
    exit 0
fi

# 3. 检测变更范围
if [ "$FORCE_REBUILD" = true ]; then
    CH_BACKEND=true; CH_FRONTEND=true; CH_QUADLET=true
    CH_PG_IMAGE=true; CH_MIGRATIONS=true
    warn "强制重建：忽略 git diff"
else
    DIFF=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD")
    matches() { echo "$DIFF" | grep -qE "$1"; }

    CH_BACKEND=$(matches '^backend/'                          && echo true || echo false)
    CH_FRONTEND=$(matches '^(frontend/|deploy/podman/images/frontend/)' && echo true || echo false)
    CH_QUADLET=$(matches '^deploy/podman/quadlet/'            && echo true || echo false)
    CH_PG_IMAGE=$(matches '^deploy/podman/images/postgres/'   && echo true || echo false)
    CH_MIGRATIONS=$(matches '^backend/migrations/'            && echo true || echo false)
fi

echo
echo "变更检测："
printf "  %-20s %s\n" "backend image:"  "$CH_BACKEND"
printf "  %-20s %s\n" "frontend image:" "$CH_FRONTEND"
printf "  %-20s %s\n" "postgres image:" "$CH_PG_IMAGE"
printf "  %-20s %s\n" "quadlet files:"  "$CH_QUADLET"
printf "  %-20s %s\n" "migrations:"     "$CH_MIGRATIONS"

# 4. 重建镜像
if [ "$CH_PG_IMAGE" = "true" ]; then
    step "重建 postgres 镜像"
    podman build -t localhost/datahub-postgres:latest \
        -f deploy/podman/images/postgres/Dockerfile .
fi

if [ "$CH_BACKEND" = "true" ]; then
    step "重建 backend 镜像"
    podman build -t localhost/datahub-backend:latest \
        -f backend/Dockerfile backend/
fi

if [ "$CH_FRONTEND" = "true" ]; then
    step "重建 frontend 镜像"
    podman build -t localhost/datahub-frontend:latest \
        -f deploy/podman/images/frontend/Dockerfile .
fi

# 5. 同步 Quadlet（任何 quadlet 改动或强制时）
if [ "$CH_QUADLET" = "true" ] || [ "$FORCE_REBUILD" = true ]; then
    step "同步 Quadlet 单元"
    cp deploy/podman/quadlet/* "$QUADLET_DIR/"
    systemctl --user daemon-reload
    ok "Quadlet 已更新"
fi

# 6. 滚动重启受影响的服务
step "重启受影响的服务"
restart_svc() {
    local svc=$1
    echo "  重启 $svc.service"
    systemctl --user restart "$svc.service"
    sleep 2
    if ! systemctl --user is-active --quiet "$svc.service"; then
        err "$svc 重启失败"
        journalctl --user -u "$svc.service" -n 40 --no-pager
        exit 1
    fi
}

[ "$CH_PG_IMAGE" = "true" ] && restart_svc datahub-postgres
[ "$CH_BACKEND"  = "true" ] && restart_svc datahub-backend
[ "$CH_FRONTEND" = "true" ] && restart_svc datahub-frontend

# Quadlet 改了但镜像没改时，仍需重启对应服务
if [ "$CH_QUADLET" = "true" ]; then
    DIFF_Q=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD" -- deploy/podman/quadlet/ 2>/dev/null || true)
    [ "$CH_PG_IMAGE" = "false" ] && echo "$DIFF_Q" | grep -q "datahub-postgres" && restart_svc datahub-postgres
    [ "$CH_BACKEND"  = "false" ] && echo "$DIFF_Q" | grep -q "datahub-backend"  && restart_svc datahub-backend
    [ "$CH_FRONTEND" = "false" ] && echo "$DIFF_Q" | grep -q "datahub-frontend" && restart_svc datahub-frontend
    echo "$DIFF_Q" | grep -q "datahub-rabbitmq" && restart_svc datahub-rabbitmq
fi

# 7. 迁移提示
if [ "$CH_MIGRATIONS" = "true" ] && [ "$SKIP_MIGRATE" = false ]; then
    echo
    warn "检测到新迁移文件："
    git diff --name-only "$OLD_HEAD" "$NEW_HEAD" -- backend/migrations/ | sed 's/^/  /'
    read -rp "立即执行迁移？(Y/n): " ans
    ans="${ans,,}"
    if [[ -z "$ans" || "$ans" == "y" ]]; then
        podman exec -it datahub-backend php bin/hyperf.php migrate
        ok "迁移完成"
    else
        warn "跳过。后续可手动执行：podman exec -it datahub-backend php bin/hyperf.php migrate"
    fi
elif [ "$CH_MIGRATIONS" = "true" ]; then
    warn "检测到新迁移但已 --skip-migrate，请手动执行"
fi

echo
ok "更新完成"
echo "  $OLD_HEAD"
echo "   → $NEW_HEAD"
