name: Preview Cleanup
on:
  pull_request:
    types:
    - closed
    branches:
    - main
    - develop
permissions:
  contents: read
  pull-requests: write
jobs:
  cleanup-preview:
    name: Cleanup Preview Environment
    runs-on: runtime-builder
    timeout-minutes: 10
    steps:
    - name: Checkout code
      shell: sh
      env:
        GITHUB_TOKEN: ${{ github.token }}
      run: |
        set -eu
        python3 - <<'PY'
        import io, os, tarfile, time, urllib.request, urllib.error
        url = f"{os.environ['GITHUB_API_URL']}/repos/{os.environ['GITHUB_REPOSITORY']}/archive/{os.environ['GITHUB_SHA']}.tar.gz"
        request = urllib.request.Request(url, headers={"Authorization": f"token {os.environ['GITHUB_TOKEN']}"})
        last_err = None
        for attempt in range(5):
            try:
                with urllib.request.urlopen(request, timeout=120) as response:
                    archive = response.read()
                break
            except urllib.error.HTTPError as e:
                last_err = e
                if e.code >= 500 and attempt < 4:
                    wait = 2 ** attempt
                    print(f"Checkout HTTP {e.code}, retrying in {wait}s (attempt {attempt+1}/5)...")
                    time.sleep(wait)
                    continue
                raise
            except Exception as e:
                last_err = e
                if attempt < 4:
                    wait = 2 ** attempt
                    print(f"Checkout error: {e}, retrying in {wait}s (attempt {attempt+1}/5)...")
                    time.sleep(wait)
                    continue
                raise
        else:
            raise last_err
        with tarfile.open(fileobj=io.BytesIO(archive), mode='r:gz') as tar:
            root_prefix = tar.getmembers()[0].name.split('/', 1)[0] + '/'
            for member in tar.getmembers():
                name = member.name
                if name == root_prefix[:-1]:
                    continue
                if name.startswith(root_prefix):
                    member.name = name[len(root_prefix):]
                if member.name:
                    tar.extract(member, '.')
        PY

    - name: Extract PR number
      shell: sh
      run: |
        set -eu
        # 优先从event payload中读取（兼容所有PR事件类型）
        if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -f "$GITHUB_EVENT_PATH" ]; then
          PR_NUMBER=$(python3 -c "import json,sys; print(json.load(sys.stdin).get('number',''))" < "$GITHUB_EVENT_PATH")
        fi
        # fallback: 从GITHUB_REF中提取
        if [ -z "${PR_NUMBER:-}" ]; then
          PR_NUMBER=$(echo "$GITHUB_REF" | sed -n 's|refs/pull/\([0-9]*\)/.*|\1|p')
        fi
        # 再fallback: 兼容纯数字ref
        if [ -z "${PR_NUMBER:-}" ] || ! echo "$PR_NUMBER" | grep -qE '^[0-9]+$'; then
          echo "WARNING: Could not extract PR number cleanly, using raw ref suffix"
          PR_NUMBER=$(echo "$GITHUB_REF" | sed 's|refs/pull/||; s|/.*||')
        fi
        echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
        echo "PR number: $PR_NUMBER"
        echo "Preview dir: /var/www/preview/pr-${PR_NUMBER}"

    - name: Install SSH client
      shell: sh
      run: |
        set -eu
        # 先检查是否已存在ssh
        if command -v ssh >/dev/null 2>&1 && command -v ssh-keyscan >/dev/null 2>&1; then
          echo "SSH client already available: $(ssh -V 2>&1)"
          exit 0
        fi
        # 尝试多种包管理器安装
        if command -v apk >/dev/null 2>&1; then
          apk add --no-cache openssh-client >/dev/null 2>&1
          echo "openssh-client installed via apk"
        elif command -v apt-get >/dev/null 2>&1; then
          apt-get update -qq && apt-get install -y -qq openssh-client >/dev/null 2>&1
          echo "openssh-client installed via apt-get"
        elif command -v yum >/dev/null 2>&1; then
          yum install -y openssh-clients >/dev/null 2>&1
          echo "openssh-client installed via yum"
        elif command -v dnf >/dev/null 2>&1; then
          dnf install -y openssh-clients >/dev/null 2>&1
          echo "openssh-client installed via dnf"
        else
          echo "ERROR: No package manager found and ssh not pre-installed"
          which ssh 2>/dev/null || echo "  ssh: not found"
          which ssh-keyscan 2>/dev/null || echo "  ssh-keyscan: not found"
          exit 1
        fi

    - name: Remove preview directory from server
      shell: sh
      env:
        PREVIEW_SSH_HOST: ${{ secrets.PREVIEW_SSH_HOST }}
        PREVIEW_SSH_USER: ${{ secrets.PREVIEW_SSH_USER }}
        PREVIEW_SSH_PORT: ${{ secrets.PREVIEW_SSH_PORT }}
        PREVIEW_SSH_KEY: ${{ secrets.PREVIEW_SSH_KEY }}
      run: |
        set -eux
        preview_host="${PREVIEW_SSH_HOST:-47.98.113.167}"
        preview_user="${PREVIEW_SSH_USER:-root}"
        preview_port="${PREVIEW_SSH_PORT:-22222}"
        preview_dir="/var/www/preview/pr-${PR_NUMBER}"

        mkdir -p ~/.ssh

        # 查找可用的SSH密钥（优先用 secret 里专门为 preview 配置的 key）
        key_path=""
        if [ -n "${PREVIEW_SSH_KEY:-}" ]; then
          key_path="$HOME/.ssh/id_ed25519"
          printf '%s\n' "$PREVIEW_SSH_KEY" > "$key_path"
          chmod 600 "$key_path"
          echo "Using key from PREVIEW_SSH_KEY secret"
        elif [ -f /root/.ssh/xiaoxia_runtime_builder ]; then
          key_path="/root/.ssh/xiaoxia_runtime_builder"
          echo "Using key: $key_path (builder key)"
        elif [ -f "$HOME/.ssh/xiaoxia_runtime_builder" ]; then
          key_path="$HOME/.ssh/xiaoxia_runtime_builder"
          echo "Using key: $key_path (home key)"
        else
          echo "ERROR: No SSH key available"
          ls -la ~/.ssh/ 2>/dev/null || true
          ls -la /root/.ssh/ 2>/dev/null || true
          exit 1
        fi

        ssh-keyscan -p "$preview_port" -H "$preview_host" >> ~/.ssh/known_hosts 2>/dev/null
        echo "SSH keyscan done"

        # 测试SSH连接
        ssh -p "$preview_port" -i "$key_path" -o StrictHostKeyChecking=no "${preview_user}@${preview_host}" "echo SSH_CONNECTION_OK && hostname"
        echo "SSH connection verified"

        # 检查目录是否存在
        DIR_EXISTS=$(ssh -p "$preview_port" -i "$key_path" -o StrictHostKeyChecking=no "${preview_user}@${preview_host}" \
          "if [ -d '${preview_dir}' ]; then echo 'yes'; else echo 'no'; fi")

        if [ "$DIR_EXISTS" = "yes" ]; then
          echo "Removing preview directory: ${preview_dir}"
          ssh -p "$preview_port" -i "$key_path" -o StrictHostKeyChecking=no "${preview_user}@${preview_host}" \
            "rm -rf ${preview_dir} && echo 'Preview directory removed successfully'"
          echo "Cleanup completed: ${preview_dir}"
        else
          echo "Preview directory does not exist: ${preview_dir}, nothing to clean up"
        fi

    - name: Comment cleanup notice on PR
      if: success()
      shell: sh
      env:
        GITHUB_TOKEN: ${{ github.token }}
      run: |
        set -eu
        # 从event payload读取PR号（最可靠）
        if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -f "$GITHUB_EVENT_PATH" ]; then
          PR_NUMBER=$(python3 -c "import json,sys; print(json.load(sys.stdin).get('number',''))" < "$GITHUB_EVENT_PATH")
        else
          PR_NUMBER=$(echo "$GITHUB_REF" | sed -n 's|refs/pull/\([0-9]*\)/.*|\1|p')
        fi
        export PR_NUMBER

        COMMENT_BODY=$(python3 scripts/ci/preview_comment.py cleanup)

        API_URL="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments"
        curl -s -X POST \
          -H "Authorization: token ${GITHUB_TOKEN}" \
          -H "Content-Type: application/json" \
          -d "$COMMENT_BODY" \
          "$API_URL" \
          > /dev/null
        echo "Cleanup comment posted"

    - name: Report CI trace
      if: always()
      shell: sh
      env:
        AGENTLOOP_LICENSE_KEY: ${{ secrets.AGENTLOOP_LICENSE_KEY }}
      run: |
        STATUS="ok"
        [ ${{ job.status }} = "success" ] || STATUS="error"
        START_TIME=""
        [ -f /tmp/ci_job_start_time ] && START_TIME=$(cat /tmp/ci_job_start_time)
        python3 scripts/ci/ci_trace_report.py --service xiaoxia-saas-ci --status $STATUS --start-time "$START_TIME" || true

