name: Load Test Gradio Apps

on:
  workflow_dispatch:
    inputs:
      app_url:
        description: 'App URL to test (e.g., https://judge-abc123-uc.a.run.app)'
        required: true
        type: string
      session_id:
        description: 'Session ID / Auth token for the app'
        required: true
        type: string
      num_users:
        description: 'Number of concurrent users'
        required: true
        default: '100'
        type: string
      spawn_rate:
        description: 'Users spawned per second'
        required: true
        default: '10'
        type: string
      run_time:
        description: 'Test duration (e.g., 5m, 300s)'
        required: true
        default: '5m'
        type: string
  
  # Allow triggering after deployment
  workflow_call:
    inputs:
      app_url:
        description: 'App URL to test'
        required: true
        type: string
      session_id:
        description: 'Session ID / Auth token for the app'
        required: true
        type: string
      num_users:
        description: 'Number of concurrent users'
        required: false
        default: '50'
        type: string
      spawn_rate:
        description: 'Users spawned per second'
        required: false
        default: '5'
        type: string
      run_time:
        description: 'Test duration'
        required: false
        default: '3m'
        type: string

jobs:
  load-test:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      
      - name: Install Load Test Dependencies
        run: |
          pip install --upgrade pip
          pip install -r tests/load_tests/requirements.txt
      
      - name: Validate App URL
        id: validate-url
        run: |
          APP_URL="${{ github.event.inputs.app_url }}"
          
          # Validate URL format
          if [[ ! "$APP_URL" =~ ^https?:// ]]; then
            echo "❌ Invalid URL format. Must start with http:// or https://"
            exit 1
          fi
          
          echo "✅ Testing URL: $APP_URL"
          echo "url=$APP_URL" >> $GITHUB_OUTPUT
      
      - name: Run Load Test
        run: |
          cd tests/load_tests
          
          APP_URL="${{ github.event.inputs.app_url }}"
          SESSION_ID="${{ github.event.inputs.session_id }}"
          
          echo "🚀 Starting load test"
          echo "  URL: $APP_URL"
          echo "  Session ID: ${SESSION_ID:0:8}..." # Show only first 8 chars for security
          echo "  Users: ${{ github.event.inputs.num_users || '50' }}"
          echo "  Spawn Rate: ${{ github.event.inputs.spawn_rate || '5' }}"
          echo "  Duration: ${{ github.event.inputs.run_time || '3m' }}"
          
          # Determine user class based on URL pattern
          USER_CLASS="GradioAppUser"
          if [[ "$APP_URL" == *"model-building-game"* ]]; then
            USER_CLASS="ModelBuildingGameUser"
          fi
          if [[ "$APP_URL" == *"what_is_ai"* || "$APP_URL" == *"what-is-ai"* ]]; then
            USER_CLASS="WhatIsAIAppUser"
          fi
          
          # Export session ID as environment variable for the load test
          export LOAD_TEST_SESSION_ID="$SESSION_ID"
          
          # Run locust in headless mode
          # NOTE: Select user class via positional argument (no --user-class flag).
          locust -f locustfile_gradio_apps.py "$USER_CLASS" \
            --host="$APP_URL" \
            --users ${{ github.event.inputs.num_users || '50' }} \
            --spawn-rate ${{ github.event.inputs.spawn_rate || '5' }} \
            --run-time ${{ github.event.inputs.run_time || '3m' }} \
            --headless \
            --html=load_test_report.html \
            --csv=load_test_results \
            || true  # Don't fail workflow on test failures
          
          echo "✅ Load test complete"
      
      - name: Parse Test Results
        id: parse-results
        run: |
          cd tests/load_tests
          
          # Check if CSV results exist
          if [ ! -f "load_test_results_stats.csv" ]; then
            echo "⚠️  No results file found"
            echo "success=false" >> $GITHUB_OUTPUT
            exit 0
          fi
          
          # Parse CSV results (skip header, get totals)
          STATS=$(tail -n 1 "load_test_results_stats.csv")
          
          # Extract metrics (CSV format: Type,Name,Request Count,Failure Count,...)
          TOTAL_REQUESTS=$(echo "$STATS" | cut -d',' -f3)
          FAILED_REQUESTS=$(echo "$STATS" | cut -d',' -f4)
          MEDIAN_TIME=$(echo "$STATS" | cut -d',' -f5)
          AVG_TIME=$(echo "$STATS" | cut -d',' -f6)
          
          # Calculate success rate
          if [ "$TOTAL_REQUESTS" -gt 0 ]; then
            SUCCESS_RATE=$(echo "scale=2; (($TOTAL_REQUESTS - $FAILED_REQUESTS) / $TOTAL_REQUESTS) * 100" | bc)
          else
            SUCCESS_RATE=0
          fi
          
          # Determine if test passed based on criteria
          PASS="true"
          if (( $(echo "$SUCCESS_RATE < 99" | bc -l) )); then
            PASS="false"
          fi
          
          echo "success_rate=$SUCCESS_RATE" >> $GITHUB_OUTPUT
          echo "total_requests=$TOTAL_REQUESTS" >> $GITHUB_OUTPUT
          echo "failed_requests=$FAILED_REQUESTS" >> $GITHUB_OUTPUT
          echo "median_time=$MEDIAN_TIME" >> $GITHUB_OUTPUT
          echo "avg_time=$AVG_TIME" >> $GITHUB_OUTPUT
          echo "pass=$PASS" >> $GITHUB_OUTPUT
      
      - name: Upload Test Report
        uses: actions/upload-artifact@v4
        with:
          name: load-test-report
          path: |
            tests/load_tests/load_test_report.html
            tests/load_tests/load_test_results_*.csv
          retention-days: 30
      
      - name: Comment Results Summary
        if: github.event_name == 'workflow_dispatch'
        run: |
          echo "## 📊 Load Test Results" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Configuration:**" >> $GITHUB_STEP_SUMMARY
          echo "- URL: ${{ github.event.inputs.app_url }}" >> $GITHUB_STEP_SUMMARY
          echo "- Users: ${{ github.event.inputs.num_users || '50' }}" >> $GITHUB_STEP_SUMMARY
          echo "- Spawn Rate: ${{ github.event.inputs.spawn_rate || '5' }}/sec" >> $GITHUB_STEP_SUMMARY
          echo "- Duration: ${{ github.event.inputs.run_time || '3m' }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Results:**" >> $GITHUB_STEP_SUMMARY
          echo "- Total Requests: ${{ steps.parse-results.outputs.total_requests }}" >> $GITHUB_STEP_SUMMARY
          echo "- Failed Requests: ${{ steps.parse-results.outputs.failed_requests }}" >> $GITHUB_STEP_SUMMARY
          echo "- Success Rate: ${{ steps.parse-results.outputs.success_rate }}%" >> $GITHUB_STEP_SUMMARY
          echo "- Median Response Time: ${{ steps.parse-results.outputs.median_time }}ms" >> $GITHUB_STEP_SUMMARY
          echo "- Average Response Time: ${{ steps.parse-results.outputs.avg_time }}ms" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          
          if [ "${{ steps.parse-results.outputs.pass }}" == "true" ]; then
            echo "✅ **Status:** PASS (Success Rate > 99%)" >> $GITHUB_STEP_SUMMARY
          else
            echo "❌ **Status:** FAIL (Success Rate < 99%)" >> $GITHUB_STEP_SUMMARY
          fi
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "📄 Download the full HTML report from artifacts for detailed analysis." >> $GITHUB_STEP_SUMMARY
