# VenomQA CI/CD Integration for GitHub Actions
#
# This workflow demonstrates how to integrate VenomQA into your CI/CD pipeline.
# Copy this file to .github/workflows/venomqa.yml and customize as needed.
#
# Features:
# - Matrix testing across Python versions
# - Docker Compose service orchestration
# - Journey execution with parallel groups
# - Artifact upload for reports
# - Proper exit code handling
#
# Exit codes:
# - 0: All journeys passed
# - 1: Some journeys failed
# - 2: Configuration error

name: VenomQA Journey Tests

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  # Allow manual trigger
  workflow_dispatch:
    inputs:
      journeys:
        description: 'Specific journeys to run (comma-separated, or empty for all)'
        required: false
        default: ''
      fail_fast:
        description: 'Stop on first failure'
        required: false
        default: 'false'
        type: boolean

env:
  # VenomQA configuration
  VENOMQA_BASE_URL: http://localhost:8000
  VENOMQA_TIMEOUT: 30
  VENOMQA_REPORT_DIR: reports
  # Database configuration
  POSTGRES_USER: qa
  POSTGRES_PASSWORD: ${{ secrets.QA_DB_PASSWORD || 'qapass' }}
  POSTGRES_DB: venomqa_qa
  # Redis configuration
  REDIS_URL: redis://localhost:6379/0

jobs:
  # Validate configuration before running tests
  validate:
    name: Validate Configuration
    runs-on: ubuntu-latest
    outputs:
      config_valid: ${{ steps.validate.outputs.valid }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: 'pip'

      - name: Install VenomQA
        run: |
          python -m pip install --upgrade pip
          pip install venomqa

      - name: Validate VenomQA configuration
        id: validate
        run: |
          if [ -f "qa/venomqa.yaml" ]; then
            echo "Configuration file found"
            # Validate YAML syntax
            python -c "import yaml; yaml.safe_load(open('qa/venomqa.yaml'))" || {
              echo "::error::Invalid YAML configuration"
              echo "valid=false" >> $GITHUB_OUTPUT
              exit 2
            }
            echo "valid=true" >> $GITHUB_OUTPUT
          else
            echo "::warning::No venomqa.yaml found, using defaults"
            echo "valid=true" >> $GITHUB_OUTPUT
          fi

      - name: List available journeys
        run: |
          if [ -d "qa/journeys" ]; then
            echo "Available journeys:"
            venomqa list --config qa/venomqa.yaml 2>/dev/null || echo "No journeys found"
          fi

  # Run journey tests
  test:
    name: Run Journeys (${{ matrix.group }})
    runs-on: ubuntu-latest
    needs: validate
    if: needs.validate.outputs.config_valid == 'true'

    strategy:
      fail-fast: false
      matrix:
        # Define journey groups for parallel execution
        group: [auth, checkout, api, content]
        # Optionally test across Python versions
        # python-version: ['3.10', '3.11', '3.12']

    services:
      # PostgreSQL service
      postgres:
        image: postgres:15-alpine
        env:
          POSTGRES_USER: ${{ env.POSTGRES_USER }}
          POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
          POSTGRES_DB: ${{ env.POSTGRES_DB }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

      # Redis service
      redis:
        image: redis:7-alpine
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

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

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: 'pip'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install venomqa[all]
          # Install project-specific dependencies if needed
          if [ -f "requirements.txt" ]; then
            pip install -r requirements.txt
          fi

      - name: Start application services
        run: |
          # Start your application using Docker Compose
          docker compose -f docker-compose.yml -f docker-compose.qa.yml up -d --wait
          # Wait for services to be ready
          sleep 10

      - name: Wait for API to be ready
        run: |
          echo "Waiting for API to be ready..."
          timeout 60 bash -c 'until curl -sf http://localhost:8000/health; do sleep 2; done'
          echo "API is ready!"

      - name: Run VenomQA journeys
        id: run_journeys
        run: |
          # Create reports directory
          mkdir -p ${{ env.VENOMQA_REPORT_DIR }}

          # Determine which journeys to run
          JOURNEY_FILTER=""
          if [ -n "${{ github.event.inputs.journeys }}" ]; then
            JOURNEY_FILTER="${{ github.event.inputs.journeys }}"
          elif [ "${{ matrix.group }}" != "" ]; then
            # Run journeys matching the group pattern
            JOURNEY_FILTER=$(ls qa/journeys/${{ matrix.group }}_*.py 2>/dev/null | xargs -I {} basename {} .py | tr '\n' ' ' || echo "")
          fi

          # Set fail-fast option
          FAIL_FAST_FLAG=""
          if [ "${{ github.event.inputs.fail_fast }}" == "true" ]; then
            FAIL_FAST_FLAG="--fail-fast"
          fi

          # Run journeys with proper exit code handling
          set +e
          venomqa run $JOURNEY_FILTER \
            --config qa/venomqa.yaml \
            --format text \
            $FAIL_FAST_FLAG

          EXIT_CODE=$?
          echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT

          # Generate reports
          venomqa report --format junit --output ${{ env.VENOMQA_REPORT_DIR }}/junit-${{ matrix.group }}.xml
          venomqa report --format html --output ${{ env.VENOMQA_REPORT_DIR }}/report-${{ matrix.group }}.html
          venomqa report --format json --output ${{ env.VENOMQA_REPORT_DIR }}/results-${{ matrix.group }}.json

          exit $EXIT_CODE

      - name: Collect logs on failure
        if: failure()
        run: |
          mkdir -p ${{ env.VENOMQA_REPORT_DIR }}/logs
          docker compose logs > ${{ env.VENOMQA_REPORT_DIR }}/logs/docker-compose.log 2>&1 || true
          docker logs $(docker ps -aq) > ${{ env.VENOMQA_REPORT_DIR }}/logs/containers.log 2>&1 || true

      - name: Upload test reports
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: venomqa-reports-${{ matrix.group }}
          path: ${{ env.VENOMQA_REPORT_DIR }}/
          retention-days: 30

      - name: Upload JUnit results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: junit-results-${{ matrix.group }}
          path: ${{ env.VENOMQA_REPORT_DIR }}/junit-*.xml

      - name: Cleanup
        if: always()
        run: |
          docker compose -f docker-compose.yml -f docker-compose.qa.yml down -v --remove-orphans

  # Aggregate results and determine overall status
  results:
    name: Aggregate Results
    runs-on: ubuntu-latest
    needs: test
    if: always()

    steps:
      - name: Download all reports
        uses: actions/download-artifact@v4
        with:
          pattern: venomqa-reports-*
          path: all-reports
          merge-multiple: true

      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v4
        if: always()
        with:
          report_paths: 'all-reports/junit-*.xml'
          fail_on_failure: true
          require_tests: true

      - name: Check overall status
        run: |
          if [ "${{ needs.test.result }}" == "failure" ]; then
            echo "::error::Some journey tests failed"
            exit 1
          elif [ "${{ needs.test.result }}" == "cancelled" ]; then
            echo "::warning::Tests were cancelled"
            exit 1
          else
            echo "All journey tests passed!"
          fi

  # Optional: Deploy on success
  deploy-staging:
    name: Deploy to Staging
    runs-on: ubuntu-latest
    needs: results
    if: github.ref == 'refs/heads/develop' && success()
    environment: staging

    steps:
      - name: Deploy to staging
        run: |
          echo "Deploying to staging..."
          # Add your deployment steps here
