name: Deploy Infra (Terraform Workspaces)

on:
  workflow_dispatch:

jobs:
  bootstrap:
    uses: ./.github/workflows/bootstrap-terraform.yml
    secrets: inherit

  deploy:
    needs: bootstrap
    runs-on: ubuntu-latest

    strategy:
      matrix:
        env: [dev]

    permissions:
      contents: read

    env:
      AWS_REGION: ${{ vars.AWS_REGION || 'us-east-1' }}
      TF_IN_AUTOMATION: "true"
      username: ${{ secrets.AIMODELSHARE_USERNAME }}
      password: ${{ secrets.AIMODELSHARE_PASSWORD }}
      AWS_ACCESS_KEY_ID: ${{ secrets.DATA_AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.DATA_AWS_SECRET_ACCESS_KEY }}

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.9.5

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.DATA_AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.DATA_AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: (Optional) Build Lambda Layer
        working-directory: infra/layer
        run: |
          if [ -f requirements.txt ]; then
            bash build_layer.sh || true
          fi

      - name: Terraform Init
        working-directory: infra
        run: terraform init -input=false

      - name: Select/Create Workspace
        working-directory: infra
        run: |
          set -euo pipefail

          WS="${{ matrix.env }}"
            echo "Ensuring Terraform workspace '${WS}' exists..."
          if terraform workspace list | sed 's/^[* ]*//' | grep -Fxq "$WS"; then
            echo "Selecting existing workspace: $WS"
            terraform workspace select "$WS"
          else
            echo "Creating new workspace: $WS"
            terraform workspace new "$WS"
          fi
          echo "Current workspace: $(terraform workspace show)"

          if [ ! -d .terraform ]; then
            echo "Terraform not initialized yet; running 'terraform init'..."
            terraform init -input=false
          fi

          STATE_KEY="env:/${WS}/aimodelshare/infra/terraform.tfstate"
          echo "Checking if remote state object exists: ${STATE_KEY}"
          if aws s3api head-object --bucket "aimodelshare-tfstate-prod-copilot-2024" --key "${STATE_KEY}" >/dev/null 2>&1; then
            echo "Remote state object exists for workspace '${WS}'"
          else
            echo "Remote state object missing for workspace '${WS}' - creating initial state"
            terraform apply -auto-approve -target=null_resource.state_seed
          fi

          echo "Workspace '$WS' ready; proceeding to plan/apply steps."

      - name: Terraform Validate
        working-directory: infra
        run: terraform validate

      - name: Terraform Plan
        id: plan
        working-directory: infra
        run: terraform plan -input=false -out=tfplan

      - name: Terraform Apply
        if: github.ref == 'refs/heads/master'
        working-directory: infra
        run: terraform apply -input=false -auto-approve tfplan

      - name: Show Outputs
        working-directory: infra
        run: terraform output -json

      - name: Wait for DynamoDB GSI readiness
        if: github.ref == 'refs/heads/master'
        working-directory: infra
        run: |
          TABLE_NAME=$(terraform output -raw dynamodb_table_name)
          echo "Waiting for GSI 'byUser' on table $TABLE_NAME to become ACTIVE..."
          ATTEMPTS=0
          MAX_ATTEMPTS=30
          SLEEP_SECONDS=5
          while true; do
            STATUS=$(aws dynamodb describe-table --table-name "$TABLE_NAME" \
              --query "Table.GlobalSecondaryIndexes[?IndexName=='byUser'].IndexStatus" --output text 2>/dev/null || echo "UNKNOWN")
            if [ "$STATUS" = "ACTIVE" ]; then
              echo "GSI 'byUser' is ACTIVE."
              break
            fi
            ATTEMPTS=$((ATTEMPTS+1))
            if [ $ATTEMPTS -ge $MAX_ATTEMPTS ]; then
              echo "Timeout waiting for GSI 'byUser' to become ACTIVE (last status: $STATUS)"
              exit 1
            fi
            echo "Attempt $ATTEMPTS/$MAX_ATTEMPTS: status=$STATUS; sleeping $SLEEP_SECONDS s..."
            sleep $SLEEP_SECONDS
          done

      - name: Cache Terraform Outputs
        if: github.ref == 'refs/heads/master'
        working-directory: .
        run: |
          bash scripts/cache_terraform_outputs.sh

      - name: Verify API Health Endpoint
        if: github.ref == 'refs/heads/master'
        working-directory: .
        run: |
          bash scripts/verify_api_reachable.sh

      - name: Install Package in Editable Mode
        if: github.ref == 'refs/heads/master'
        working-directory: .
        run: |
          python -m pip install --upgrade pip
          python -m pip install -e .

      - name: Run moral_compass Integration Tests
        if: github.ref == 'refs/heads/master'
        working-directory: .
        run: |
          python -m pip install pytest
          pytest -m test_moral_compass_client_auth.py -v

      - name: Run API Integration Tests
        if: github.ref == 'refs/heads/master'
        working-directory: .
        run: |
          API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
          echo "API Base URL: $API_BASE_URL"

          if [[ -z "$API_BASE_URL" || "$API_BASE_URL" == "null" ]]; then
            echo "❌ Failed to get API base URL from Terraform outputs"
            exit 1
          fi

          python -m pip install --upgrade pip
          python -m pip install requests

          echo "⏳ Extra stabilization wait (30s) after GSI readiness..."
          sleep 30

          echo "🚀 Starting API Integration Tests..."
          python tests/test_api_integration.py "$API_BASE_URL"

      - name: Run Pagination Tests
        if: github.ref == 'refs/heads/master'
        working-directory: .
        run: |
          API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
          echo "API Base URL: $API_BASE_URL"
          python -m pip install requests
          python tests/test_api_pagination.py "$API_BASE_URL"

      - name: Install Load Test Dependencies
        if: github.ref == 'refs/heads/master' && (vars.RUN_LOAD_TESTS != 'false')
        working-directory: .
        run: |
          python -m pip install aiohttp rich

      - name: Run Load Tests - Single Table
        if: github.ref == 'refs/heads/master' && (vars.RUN_LOAD_TESTS != 'false')
        working-directory: .
        run: |
          API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
          export API_BASE_URL
          echo "🚀 Running Single Table Load Test..."
          python tests/load_single_table.py

      - name: Run Load Tests - Multi Table
        if: github.ref == 'refs/heads/master' && (vars.RUN_LOAD_TESTS != 'false')
        working-directory: .
        run: |
          API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
          export API_BASE_URL
          echo "🚀 Running Multi Table Load Test..."
          python tests/load_multi_table.py

      - name: Run Load Tests - Mixed Duration
        if: github.ref == 'refs/heads/master' && (vars.RUN_LOAD_TESTS != 'false')
        working-directory: .
        env:
          LOAD_DURATION_SECONDS: 20
        run: |
          API_BASE_URL=$(cd infra && terraform output -raw api_base_url)
          export API_BASE_URL
          echo "🚀 Running Mixed Duration Load Test (20s for CI)..."
          python tests/load_mixed_duration.py
