name: Unified Tests (Fly Runner)

on:
  push:
    branches: [main]
    paths:
      - 'src/**'
      - 'tests/**'

permissions:
  contents: read
  actions: read

jobs:
  start-runner:
    name: Start Fly Runner
    uses: ./.github/workflows/start-fly-runner.yml
    secrets: inherit

  unified-tests:
    name: Run Unified Tests
    runs-on: ${{ fromJSON(format('[{0}]', needs.start-runner.outputs.runner-labels)) }}
    needs: start-runner
    if: needs.start-runner.outputs.runner-ready == 'true'
    timeout-minutes: 90
    environment: unified-tests
    permissions:
      id-token: write  # Required for OIDC authentication with AWS
      contents: read

    env:
      PYTHONUNBUFFERED: "1"
      TEST_DISCORD_WEBHOOK_URL: ${{ secrets.TEST_DISCORD_WEBHOOK_URL }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          ref: ${{ github.sha }}

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::444554165670:role/GitHubActionsS3Role
          aws-region: us-east-1
          role-duration-seconds: 43200 # 12 hours

      - name: Fetch secrets from AWS Secrets Manager
        uses: aws-actions/aws-secretsmanager-get-secrets@v2
        with:
          secret-ids: |
            ,testing/unified/tests
          parse-json-secrets: true

      - name: Verify Docker is available
        run: docker info

      - name: Verify uv and Python
        run: |
          uv --version
          python3.12 --version
          which python3.12

      - name: Install the project
        run: uv sync --all-extras

      - name: Run unified tests
        run: uv run python -m tests.unified.run

  cleanup-machine:
    name: Cleanup Fly Machine and Runner
    runs-on: ubuntu-latest
    needs: [start-runner, unified-tests]
    if: always() && needs.start-runner.outputs.machine-id != ''
    env:
      FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN_TESTING }}
      GITHUB_TOKEN: ${{ secrets.GH_TOKEN_ACTIONS }}
      FLY_RUNNER_APP: ivysaur
    steps:
      - name: Setup Fly CLI
        uses: superfly/flyctl-actions/setup-flyctl@1.5

      - name: Cleanup fly machine
        run: |
          set -euo pipefail
          MACHINE_ID="${{ needs.start-runner.outputs.machine-id }}"
          if [ -z "$MACHINE_ID" ]; then
            echo "No machine ID provided, skipping Fly cleanup."
            exit 0
          fi

          echo "🧹 Cleaning up machine: $MACHINE_ID"
          flyctl machines stop "$MACHINE_ID" -a "$FLY_RUNNER_APP" || echo "Machine may already be stopped"
          flyctl machines destroy "$MACHINE_ID" -a "$FLY_RUNNER_APP" --force || echo "Failed to destroy machine"

      - name: Cleanup GitHub runner
        run: |
          set -euo pipefail
          RUNNER_NAME="${{ needs.start-runner.outputs.runner-name }}"
          FALLBACK_LABEL="${{ github.run_id }}"

          echo "🗑️ Cleaning up GitHub runner (name: ${RUNNER_NAME:-unknown}, label: ${FALLBACK_LABEL})"

          RUNNERS_RESPONSE=$(curl -s \
            -H "Authorization: Bearer $GITHUB_TOKEN" \
            -H "Accept: application/vnd.github+json" \
            "https://api.github.com/repos/${{ github.repository }}/actions/runners")

          if echo "$RUNNERS_RESPONSE" | grep -q '"message"'; then
            echo "⚠️ Failed to fetch runners: $(echo "$RUNNERS_RESPONSE" | jq -r '.message')"
            exit 0
          fi

          RUNNER_ID="" 
          if [ -n "$RUNNER_NAME" ]; then
            RUNNER_ID=$(echo "$RUNNERS_RESPONSE" | jq -r --arg name "$RUNNER_NAME" '.runners[]? | select(.name == $name) | .id')
          fi

          if [ -z "$RUNNER_ID" ]; then
            RUNNER_ID=$(echo "$RUNNERS_RESPONSE" | jq -r --arg label "$FALLBACK_LABEL" '.runners[]? | select([.labels[].name] | index($label)) | .id' | head -n 1)
          fi

          if [ -z "$RUNNER_ID" ] || [ "$RUNNER_ID" = "null" ]; then
            echo "⚠️ Runner not found, nothing to delete."
            exit 0
          fi

          DELETE_RESPONSE=$(curl -s -w "%{http_code}" \
            -X DELETE \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: Bearer $GITHUB_TOKEN" \
            "https://api.github.com/repos/${{ github.repository }}/actions/runners/$RUNNER_ID")

          HTTP_CODE="${DELETE_RESPONSE: -3}"
          if [ "$HTTP_CODE" = "204" ]; then
            echo "✅ Successfully deleted runner."
          else
            echo "⚠️ Failed to delete runner. HTTP code: $HTTP_CODE"
            echo "Response: ${DELETE_RESPONSE%???}"
          fi
