name: Build and Publish Server

on:
  push:
    branches:
      - main
    paths:
      - "server/**"
      - ".gitea/workflows/server-deploy.yml"

jobs:
  build:
    # 标准标签：hk / bt-runner 均带 ubuntu-latest，任一空闲 runner 接单
    runs-on: ubuntu-latest
    steps:
      # 精简 runner（Alpine）无 node，无法跑 action-checkout；直接用 git 浅克隆
      - name: Checkout
        env:
          REPO_URL: ${{ gitea.server_url }}/${{ gitea.repository }}
          REF_NAME: ${{ gitea.ref_name }}
        run: |
          git init -q .
          git remote add origin "$REPO_URL"
          git fetch -q --depth 20 origin "$REF_NAME"
          git checkout -q FETCH_HEAD
          git log --oneline -3

      - name: Ensure curl available
        run: |
          # 精简 runner（Alpine 等）可能未预装 curl，发布 release 需要它
          if ! command -v curl >/dev/null 2>&1; then
            if command -v apk >/dev/null 2>&1; then apk add --no-cache curl
            elif command -v apt-get >/dev/null 2>&1; then apt-get update -qq && apt-get install -y -qq curl
            elif command -v dnf >/dev/null 2>&1; then dnf install -y -q curl
            else echo "无法安装 curl"; exit 1; fi
          fi
          curl --version | head -1

      - name: Prepare Go toolchain
        run: |
          # 优先复用 runner 宿主机缓存的工具链（工作目录持久化）
          TOOLDIR="$RUNNER_WORKSPACE/.lunar-toolchain"
          mkdir -p "$TOOLDIR"
          if [ -x "$TOOLDIR/go/bin/go" ]; then
            echo "复用缓存 Go 工具链"
          else
            # 官方源与阿里云镜像双通道，先到先用
            wget -q --tries=2 --timeout=60 -O "$TOOLDIR/go.tgz" \
              "https://go.dev/dl/go1.22.10.linux-amd64.tar.gz" \
              || wget -q --tries=2 --timeout=60 -O "$TOOLDIR/go.tgz" \
              "https://mirrors.aliyun.com/golang/go1.22.10.linux-amd64.tar.gz"
            rm -rf "$TOOLDIR/go"
            tar -C "$TOOLDIR" -xzf "$TOOLDIR/go.tgz"
            rm -f "$TOOLDIR/go.tgz"
          fi
          "$TOOLDIR/go/bin/go" version
          echo "LUNAR_GO=$TOOLDIR/go/bin/go" >> "$GITEA_ENV"

      - name: Install dependencies
        working-directory: server
        run: |
          export HOME="$RUNNER_WORKSPACE"
          "$LUNAR_GO" mod download

      - name: Run tests
        working-directory: server
        run: |
          export HOME="$RUNNER_WORKSPACE"
          "$LUNAR_GO" test ./...

      - name: Build application
        working-directory: server
        env:
          GITEA_SHA: ${{ gitea.sha }}
          GITEA_RUN_NUMBER: ${{ gitea.run_number }}
        run: |
          export HOME="$RUNNER_WORKSPACE"
          mkdir -p bin

          # 生成版本号（基线 1.1 + 构建编号，与小程序版本段对齐）
          VERSION="1.1.${GITEA_RUN_NUMBER}"
          BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
          COMMIT_SHORT="${GITEA_SHA:0:7}"

          echo "Building server version: $VERSION"

          # ldflags 注入版本信息；目标平台为 doc79（linux/amd64）
          CGO_ENABLED=0 GOOS=linux GOARCH=amd64 "$LUNAR_GO" build -ldflags "\
            -X main.Version=$VERSION \
            -X main.BuildTime=$BUILD_TIME \
            -X main.CommitSha=$COMMIT_SHORT" \
            -o bin/server cmd/main.go

          # 版本元数据随包分发，便于服务器侧追溯
          cat > bin/version.env <<EOF
          APP_VERSION=$VERSION
          APP_BUILD_TIME=$BUILD_TIME
          APP_COMMIT_SHA=$COMMIT_SHORT
          EOF
          cat bin/version.env
          # 注意：不写入 GITEA_ENV，避免跨步骤/跨运行残留值干扰发布步骤

      - name: Create deployment package
        working-directory: server
        run: |
          mkdir -p deploy
          cp -r bin/ deploy/
          cp -r migrations/ deploy/
          cp -r scripts/ deploy/
          # 管理后台静态资源必须随包发布（服务以相对路径 ./web 提供）
          if [ -d "web" ]; then
            cp -r web/ deploy/web/
          fi
          tar -czf deploy.tar.gz deploy/
          sha256sum deploy.tar.gz

      - name: Publish release with deployment package
        env:
          GITEA_SHA: ${{ gitea.sha }}
          GITEA_RUN_NUMBER: ${{ gitea.run_number }}
          LUNAR_PUBLISH_TOKEN: ${{ secrets.LUNAR_PUBLISH_TOKEN }}
        run: |
          set -e
          # 自行计算版本号；绝不复用环境中的 SERVER_VERSION（GITEA_ENV 会跨步骤持久化，
          # 可能残留早期运行的旧值，曾导致构建 1.1.48 却发布成 1.0.48）
          unset SERVER_VERSION
          VERSION="1.1.${GITEA_RUN_NUMBER}"
          TAG="server-v${VERSION}"
          API="https://gitea.neatcn.com/api/v1/repos/gouki/lunar-mini"
          # 优先用仓库 Secret 令牌（GITEA_TOKEN 内建令牌在部分 runner 版本不注入）
          TOKEN="${LUNAR_PUBLISH_TOKEN:-$GITEA_TOKEN}"
          test -n "$TOKEN"
          AUTH="Authorization: token $TOKEN"

          # 幂等：同 tag 已存在则先删除（重跑场景）；不依赖 python3，纯 grep/sed 解析
          EXISTING=$(curl -sS -H "$AUTH" "$API/releases/tags/$TAG" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2 || true)
          if [ -n "$EXISTING" ]; then
            curl -sS -X DELETE -H "$AUTH" "$API/releases/$EXISTING" -o /dev/null -w "删除旧 release: HTTP %{http_code}\n"
          fi

          CREATE_RESP=$(curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
            -d "{\"tag_name\":\"$TAG\",\"name\":\"server $VERSION\",\"target_commitish\":\"main\",\"body\":\"CI 自动构建，commit ${GITEA_SHA:0:7}。doc79 由 deploy-watch.sh 拉取本附件完成部署。\"}" \
            "$API/releases")
          RELEASE_ID=$(printf '%s' "$CREATE_RESP" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2 || true)
          if [ -z "$RELEASE_ID" ]; then
            echo "创建 release 失败，API 响应: $CREATE_RESP"
            exit 1
          fi
          echo "Release created: id=$RELEASE_ID tag=$TAG"

          curl -sS -X POST -H "$AUTH" \
            -F "attachment=@server/deploy.tar.gz" \
            "$API/releases/$RELEASE_ID/assets" \
            -o /dev/null -w "附件上传: HTTP %{http_code}\n"
          echo "发布地址: https://gitea.neatcn.com/gouki/lunar-mini/releases/tag/$TAG"

      - name: Cleanup old releases (keep latest 10)
        env:
          LUNAR_PUBLISH_TOKEN: ${{ secrets.LUNAR_PUBLISH_TOKEN }}
        run: |
          # 只保留最近 10 个 server-v* 发布，避免附件无限堆积占满磁盘
          API="https://gitea.neatcn.com/api/v1/repos/gouki/lunar-mini"
          TOKEN="${LUNAR_PUBLISH_TOKEN:-$GITEA_TOKEN}"
          AUTH="Authorization: token $TOKEN"
          KEEP=10

          # Gitea Release JSON 中 id 与 tag_name 相邻且按新到旧排序；
          # 附件随 release 删除一并清理
          PAIRS=$(curl -sS -H "$AUTH" "$API/releases?limit=50" \
            | grep -oE '"id":[0-9]+,"tag_name":"server-v[^"]*"' || true)
          TOTAL=$(printf '%s\n' "$PAIRS" | grep -c '"id"' || true)
          if [ "$TOTAL" -le "$KEEP" ]; then
            echo "当前 $TOTAL 个发布版本，未超过 $KEEP，无需清理"
            exit 0
          fi

          printf '%s\n' "$PAIRS" | tail -n +$((KEEP + 1)) | while IFS= read -r line; do
            [ -z "$line" ] && continue
            RID=$(printf '%s' "$line" | grep -oE '"id":[0-9]+' | cut -d: -f2)
            RTAG=$(printf '%s' "$line" | sed 's/.*"tag_name":"\([^"]*\)".*/\1/')
            curl -sS -X DELETE -H "$AUTH" "$API/releases/$RID" -o /dev/null -w "删除旧发布 $RTAG: HTTP %{http_code}\n"
            # 同步删除自动创建的 tag，避免 tag 堆积
            curl -sS -X DELETE -H "$AUTH" "$API/tags/$RTAG" -o /dev/null -w "删除 tag $RTAG: HTTP %{http_code}\n"
          done

      - name: Send success notification
        if: success()
        env:
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
          DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
          GITEA_RUN_NUMBER: ${{ gitea.run_number }}
        run: |
          VERSION="1.1.${GITEA_RUN_NUMBER}"
          bash .gitea/scripts/notify.sh success \
            "后端构建发布成功" \
            "版本: v${VERSION}\n产物: releases/tag/server-v${VERSION}\ndoc79 将自动拉取部署" || echo "通知发送失败，不影响主流程"

      - name: Send failure notification
        if: failure()
        env:
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
          DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
        run: |
          bash .gitea/scripts/notify.sh failure \
            "后端构建失败" \
            "请检查 Actions 日志了解失败原因" || echo "通知发送失败"

      - name: Cleanup
        if: always()
        run: |
          rm -rf server/deploy/
          rm -f server/deploy.tar.gz
