#!/bin/bash
# 拉取式部署 watcher - 从 Gitea Release 拉取最新部署包并自动部署
# 设计原则：
#   - CI 在任意 runner（hk 等）构建，产物以 Release 附件发布到 Gitea
#   - 本脚本由服务器本地定时任务（1Panel 计划任务）每分钟调用，通过 HTTPS 拉取，
#     任何 AI/CI 均不通过 SSH 操作服务器
# 安装方式见 .gitea/docs/PULL_DEPLOY.md（1Panel 原生方式，一次性配置）
#
# 可选环境变量（建议写入 /opt/lunar/production/.env 并在计划任务里 source）：
#   GITEA_DEPLOY_TOKEN  只读令牌（仓库公开时可省略，匿名即可下载）

set -u

GITEA_URL="${GITEA_URL:-https://gitea.neatcn.com}"
REPO="${REPO:-gouki/lunar-mini}"
STATE_FILE="${STATE_FILE:-/opt/lunar/production/.last-deployed-release}"
DEPLOY_SCRIPT="${DEPLOY_SCRIPT:-/opt/lunar/scripts/deploy.sh}"
LOG_FILE="${LOG_FILE:-/opt/lunar/deploy-watch.log}"
WORK_DIR="$(mktemp -d)"
trap 'rm -rf "$WORK_DIR"' EXIT

log() {
  echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOG_FILE"
}

AUTH_ARGS=()
if [ -n "${GITEA_DEPLOY_TOKEN:-}" ]; then
  AUTH_ARGS=(-H "Authorization: token ${GITEA_DEPLOY_TOKEN}")
fi

# 查询最新 20 个 release，取 tag 前缀为 server-v 且带 deploy.tar.gz 附件的最新一个
RELEASE_JSON=$(curl -fsS --connect-timeout 10 --max-time 30 \
  "${AUTH_ARGS[@]}" \
  "$GITEA_URL/api/v1/repos/$REPO/releases?limit=20" \
  -o "$WORK_DIR/releases.json" && cat "$WORK_DIR/releases.json") || {
  log "查询 release 列表失败，等待下次轮询"
  exit 1
}

PARSED=$(python3 - "$WORK_DIR/releases.json" <<'PY'
import json, sys
releases = json.load(open(sys.argv[1]))
for r in releases:
    if not r.get("tag_name", "").startswith("server-v"):
        continue
    if r.get("draft") or r.get("prerelease"):
        continue
    for a in r.get("assets", []):
        if a.get("name") == "deploy.tar.gz":
            print(r["id"])
            print(r["tag_name"])
            print(a["id"])
            print(a["browser_download_url"])
            sys.exit(0)
PY
) || true

if [ -z "$PARSED" ]; then
  # 尚无可部署的发布版本，静默等待
  exit 0
fi

RELEASE_ID=$(echo "$PARSED" | sed -n 1p)
TAG=$(echo "$PARSED" | sed -n 2p)
ASSET_ID=$(echo "$PARSED" | sed -n 3p)
DOWNLOAD_URL=$(echo "$PARSED" | sed -n 4p)

# 幂等：已部署过该 release 则跳过
LAST="$(cat "$STATE_FILE" 2>/dev/null || true)"
if [ "$LAST" = "$RELEASE_ID" ]; then
  exit 0
fi

log "发现新版本 $TAG (release #$RELEASE_ID)，开始拉取部署"

# 下载部署包（公开仓库可匿名；-L 跟随重定向）
if ! curl -fsSL --connect-timeout 10 --max-time 300 \
  "${AUTH_ARGS[@]}" \
  "$DOWNLOAD_URL" -o "$WORK_DIR/deploy.tar.gz"; then
  log "下载部署包失败，等待下次轮询重试"
  exit 1
fi

# 包结构预检（deploy.sh 内部还会再校验）
if ! tar -tzf "$WORK_DIR/deploy.tar.gz" | grep -q "^deploy/bin/server$"; then
  log "部署包结构异常（缺少 deploy/bin/server），中止"
  exit 1
fi

# 执行部署；成功后才记录 release id（失败时下次轮询会重试）
if bash "$DEPLOY_SCRIPT" "$WORK_DIR/deploy.tar.gz" >> "$LOG_FILE" 2>&1; then
  mkdir -p "$(dirname "$STATE_FILE")"
  printf '%s' "$RELEASE_ID" > "$STATE_FILE"
  log "部署成功: $TAG"
else
  log "部署失败（$TAG），保留旧版本，等待下次轮询重试或人工介入"
  exit 1
fi
