name: ACR Cleanup

on:
  schedule:
    - cron: '0 19 * * *'  # UTC 19:00 = 北京时间凌晨3:00
  workflow_dispatch:
    inputs:
      pr_sha:
        description: "PR commit SHA（仅清理指定PR镜像，留空则全量清理）"
        required: false
        default: ""
      dry_run:
        description: "预览模式（dry-run），不实际删除"
        required: false
        default: "true"
  pull_request_target:
    types: [closed]
    branches: [develop, main]

concurrency:
  group: acr-cleanup-${{ gitea.ref }}
  cancel-in-progress: false

jobs:
  cleanup:
    name: ACR Image Cleanup
    runs-on: ci-l2
    timeout-minutes: 20
    permissions:
      contents: read
    env:
      ACR_REGISTRY: xiaoxia-registry.cn-hangzhou.cr.aliyuncs.com
      ACR_NAMESPACE: xiaoxiakeji
      ACR_SERVICE: registry.aliyuncs.com:cn-hangzhou:china:cri-fvec8o9q4mmxrkaa
      GITEA_URL: https://git.xiaoxiajianji.com
      GITEA_REPO: xiaoxia/xiaoxia-saas
    steps:
      - name: Checkout code
        shell: sh
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |
          curl -sH "Authorization: token $GITHUB_TOKEN"             "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/raw/scripts/ci/step_checkout.sh?ref=${GITHUB_SHA}"             | bash

      # ====== Cron模式：获取staging运行中镜像作为白名单 ======
      - name: Get staging running images (whitelist)
        id: protected_images
        if: gitea.event_name != 'pull_request_target' && !gitea.event.inputs.pr_sha
        env:
          STAGING_SSH_HOST: ${{ secrets.STAGING_SSH_HOST }}
          STAGING_SSH_PORT: ${{ secrets.STAGING_SSH_PORT }}
          STAGING_SSH_USER: ${{ secrets.STAGING_SSH_USER }}
          STAGING_SSH_KEY: ${{ secrets.STAGING_SSH_KEY }}
        run: |
          set +e
          echo "获取staging服务器运行中镜像作为白名单..."
          staging_host="${STAGING_SSH_HOST:-47.98.113.167}"
          staging_port="${STAGING_SSH_PORT:-22222}"
          staging_user="${STAGING_SSH_USER:-root}"

          key_path=~/.ssh/id_rsa
          if [ -n "${STAGING_SSH_KEY:-}" ]; then
            printf '%s\n' "$STAGING_SSH_KEY" > "$key_path"
            chmod 600 "$key_path"
            echo "Using key from STAGING_SSH_KEY secret"
          else
            echo "⚠️  STAGING_SSH_KEY not set, skipping whitelist"
            echo "protected_tags=" >> $GITHUB_OUTPUT
            exit 0
          fi

          ssh-keyscan -p "$staging_port" -H "$staging_host" >> ~/.ssh/known_hosts 2>/dev/null

          # 获取所有运行容器的镜像，提取tag部分
          IMAGES=$(ssh -p "$staging_port" -i "$key_path" -o StrictHostKeyChecking=no \
            "$staging_user@$staging_host" "docker ps --format '{{.Image}}' 2>/dev/null" 2>/dev/null | grep -v "^$" | sort -u)

          PROTECTED_TAGS=""
          if [ -n "$IMAGES" ]; then
            while IFS= read -r img; do
              # 从完整镜像名中提取tag（最后一个冒号后）
              tag=$(echo "$img" | rev | cut -d: -f1 | rev)
              if [ -n "$tag" ] && [ "$tag" != "latest" ] && [ ${#tag} -gt 5 ]; then
                if [ -z "$PROTECTED_TAGS" ]; then
                  PROTECTED_TAGS="$tag"
                else
                  PROTECTED_TAGS="$PROTECTED_TAGS,$tag"
                fi
              fi
            done <<< "$IMAGES"
          fi

          echo "staging运行中镜像tag: ${PROTECTED_TAGS:-（无）}"
          echo "protected_tags=$PROTECTED_TAGS" >> $GITHUB_OUTPUT

      # ====== Docker登录 ======
      - name: Docker login to ACR
        env:
          ACR_USERNAME: ${{ secrets.ACR_USERNAME }}
          ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }}
        run: |
          printf '%s' "$ACR_PASSWORD" | docker login "$ACR_REGISTRY" -u "$ACR_USERNAME" --password-stdin

      # ====== 模式1：PR关闭时清理 ======
      - name: Cleanup PR images (PR closed)
        if: gitea.event_name == 'pull_request_target'
        env:
          ACR_USERNAME: ${{ secrets.ACR_USERNAME }}
          ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }}
          GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
          PR_SHA: ${{ gitea.event.pull_request.head.sha }}
          PR_NUMBER: ${{ gitea.event.pull_request.number }}
        run: |
          echo "============================================"
          echo "  PR #$PR_NUMBER 已关闭，清理对应镜像"
          echo "  Head SHA: ${PR_SHA::12}"
          echo "============================================"
          echo ""
          python3 scripts/ci/acr_cleanup.py \
            --pr-sha "$PR_SHA" \
            --execute

      # ====== 模式2：Cron全量清理 ======
      - name: Full cleanup (cron / manual)
        if: gitea.event_name != 'pull_request_target' && !gitea.event.inputs.pr_sha
        env:
          ACR_USERNAME: ${{ secrets.ACR_USERNAME }}
          ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }}
          GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
          PROTECTED_TAGS: ${{ steps.protected_images.outputs.protected_tags }}
          DRY_RUN_INPUT: ${{ gitea.event.inputs.dry_run }}
        run: |
          echo "============================================"
          echo "  ACR 全量清理（${{ gitea.event_name }}）"
          echo "============================================"
          echo ""

          # 决定是否dry-run
          DRY_RUN_FLAG=""
          if [ "$DRY_RUN_INPUT" = "true" ]; then
            DRY_RUN_FLAG="--dry-run"
            echo "模式: 预览模式 (dry-run)"
          else
            echo "模式: 执行模式"
          fi
          echo ""

          python3 scripts/ci/acr_cleanup.py \
            --keep 20 \
            --protected-tags "$PROTECTED_TAGS" \
            $DRY_RUN_FLAG

      # ====== 模式3：手动指定PR SHA清理 ======
      - name: Cleanup specific PR image (manual)
        if: gitea.event_name == 'workflow_dispatch' && gitea.event.inputs.pr_sha
        env:
          ACR_USERNAME: ${{ secrets.ACR_USERNAME }}
          ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }}
          PR_SHA: ${{ gitea.event.inputs.pr_sha }}
          DRY_RUN_INPUT: ${{ gitea.event.inputs.dry_run }}
        run: |
          echo "手动清理PR镜像: ${PR_SHA::12}"
          echo ""

          DRY_RUN_FLAG=""
          if [ "$DRY_RUN_INPUT" = "true" ]; then
            DRY_RUN_FLAG="--dry-run"
          fi

          python3 scripts/ci/acr_cleanup.py \
            --pr-sha "$PR_SHA" \
            $DRY_RUN_FLAG
