name: CFC Testing & Validation

on:
  push:
    branches: [ develop ]
    paths:
      - 'cloudforge-core/**'
      - 'cloudforge-api/**'
      - 'cfc-testing/**'
      - 'pom.xml'
      - '**/pom.xml'
  pull_request:
    branches: [ develop ]
    paths:
      - 'cloudforge-core/**'
      - 'cloudforge-api/**'
      - 'cfc-testing/**'
      - 'pom.xml'
      - '**/pom.xml'
  workflow_dispatch:
    inputs:
      validation_mode:
        description: 'Validation mode to run'
        required: true
        type: choice
        options:
          - smoke
          - validate
          - full
          - drift
        default: 'smoke'

jobs:
  cfc-validation:
    name: CFC Configuration Validation
    runs-on: ubuntu-latest
    timeout-minutes: 60

    permissions:
      contents: read
      pull-requests: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for drift detection

      - name: Set up JDK 25
        uses: actions/setup-java@v4
        with:
          java-version: '25'
          distribution: 'temurin'
          cache: 'maven'

      - name: Install dependencies
        run: |
          echo "Installing required dependencies..."
          sudo apt-get update
          sudo apt-get install -y jq python3 python3-pip
          pip3 install --upgrade pip
          echo "Dependencies installed"

      - name: Install AWS CDK
        run: |
          echo "Installing AWS CDK..."
          npm install -g aws-cdk
          cdk --version
          echo "AWS CDK installed"

      - name: Configure AWS credentials (for CDK synth only)
        env:
          # Mock credentials for CDK synthesis only - not used for actual AWS operations
          MOCK_AWS_ACCESS_KEY_ID: ${{ secrets.MOCK_AWS_ACCESS_KEY_ID }}
          MOCK_AWS_SECRET_ACCESS_KEY: ${{ secrets.MOCK_AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: us-east-1
        run: |
          echo "Configuring mock credentials for CDK synthesis..."
          mkdir -p ~/.aws
          cat > ~/.aws/credentials << EOF
          [default]
          aws_access_key_id = ${MOCK_AWS_ACCESS_KEY_ID}
          aws_secret_access_key = ${MOCK_AWS_SECRET_ACCESS_KEY}
          EOF
          cat > ~/.aws/config << EOF
          [default]
          region = ${AWS_DEFAULT_REGION}
          output = json
          EOF
          echo "Mock credentials configured (synth only, no deployment)"

      - name: Cache Maven dependencies
        uses: actions/cache@v4
        with:
          path: ~/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
          restore-keys: |
            ${{ runner.os }}-maven-

      - name: Build and test project
        run: |
          echo "Building and testing CFC Core..."
          mvn clean install -Pci -B -V
          echo "Build and tests complete"

      - name: Prepare CDK dependencies
        run: |
          echo "Preparing CDK dependencies for cfc-testing..."
          cd cfc-testing

          # Verify build artifacts exist
          if [ ! -d "target/classes" ]; then
            echo "Building cfc-testing module..."
            mvn clean install -DskipTests -B
          fi

          # Copy dependencies to target if not already there
          if [ ! -d "target/dependency" ]; then
            echo "Copying Maven dependencies..."
            mvn dependency:copy-dependencies -DoutputDirectory=target/dependency -B
          fi

          # Verify the CDK app can be found
          echo "Verifying CDK app class..."
          if [ -f "target/classes/com/cloudforgeci/samples/app/CloudForgeCommunitySample.class" ]; then
            echo "✅ CDK app class found"
          else
            echo "❌ ERROR: CDK app class not found"
            echo "Contents of target/classes:"
            find target/classes -type f -name "*.class" | head -10
            exit 1
          fi

          echo "CDK dependencies ready"
          echo "Target directory contents:"
          ls -la target/
          echo "Dependency count: $(ls target/dependency/*.jar 2>/dev/null | wc -l)"

      - name: Set up validation environment
        run: |
          echo "Setting up validation environment..."
          cd cfc-testing

          # Make scripts executable
          chmod +x scripts/*.sh 2>/dev/null || true
          chmod +x scripts/*.py 2>/dev/null || true

          # Create necessary directories
          mkdir -p scripts/validation-results
          mkdir -p scripts/synth-results

          echo "Validation environment ready"
          echo "Working directory: $(pwd)"

      - name: Determine validation mode
        id: mode
        run: |
          if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
            MODE="${{ github.event.inputs.validation_mode }}"
          elif [ "${{ github.event_name }}" == "pull_request" ]; then
            # Use smoke for draft PRs, full for ready-to-merge PRs
            if [ "${{ github.event.pull_request.draft }}" == "true" ]; then
              MODE="smoke"
              echo "Draft PR detected - using smoke tests for faster feedback"
            else
              MODE="full"
              echo "Ready-to-merge PR - using full validation"
            fi
          else
            MODE="validate"
          fi
          echo "mode=$MODE" >> $GITHUB_OUTPUT
          echo "Running validation mode: $MODE"

      - name: Run CFC validation
        id: validation
        continue-on-error: true
        run: |
          cd cfc-testing
          echo "Running validation mode: ${{ steps.mode.outputs.mode }}"
          echo "Current directory: $(pwd)"
          echo "Checking prerequisites..."

          # Verify dependencies
          echo "Checking jq: $(which jq)"
          echo "Checking python3: $(which python3)"
          echo "Checking cdk: $(which cdk)"
          echo "Checking mvn: $(which mvn)"

          # Verify scripts exist
          echo "Checking scripts..."
          ls -la scripts/*.sh scripts/*.py 2>/dev/null | head -5 || echo "Script listing failed"

          # Verify CDK setup
          echo "Verifying CDK setup..."
          ls -la target/classes/ | head -5 || echo "target/classes not found"
          ls -la target/dependency/ | head -5 || echo "target/dependency not found"

          # Run the appropriate validation mode
          echo "Starting validation..."
          bash scripts/master-validation-system.sh ${{ steps.mode.outputs.mode }} 2>&1 | tee validation-run.log

          # Capture exit code
          EXIT_CODE=${PIPESTATUS[0]}
          echo "Validation exit code: $EXIT_CODE"
          echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT

          # Show validation output summary
          if [ $EXIT_CODE -ne 0 ]; then
            echo ""
            echo "=========================================="
            echo "Validation failed. Error summary:"
            echo "=========================================="

            # Show smoke test error logs if they exist
            if [ -d "scripts/validation-results" ]; then
              echo "Error logs found:"
              find scripts/validation-results -name "*-error.log" -type f | while read logfile; do
                echo ""
                echo "--- $(basename $logfile) ---"
                cat "$logfile"
              done
            fi

            echo ""
            echo "Last 100 lines of validation output:"
            tail -100 validation-run.log
          else
            echo "✅ Validation passed successfully"
          fi

          exit $EXIT_CODE

      - name: Generate testing strategy for PR
        if: github.event_name == 'pull_request' && steps.mode.outputs.mode != 'smoke'
        continue-on-error: true
        run: |
          cd cfc-testing

          # Get list of changed files
          CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.(java|ts|js)$' | tr '\n' ',' | sed 's/,$//')

          if [ -n "$CHANGED_FILES" ]; then
            echo "Changed files: $CHANGED_FILES"
            bash scripts/master-validation-system.sh strategy "$CHANGED_FILES" > testing-strategy.txt
          else
            echo "No relevant files changed"
            echo "No Java/TypeScript files changed in this PR" > testing-strategy.txt
          fi

      - name: Generate validation summary
        if: always()
        run: |
          cd cfc-testing

          echo "## CFC Validation Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Validation Mode:** \`${{ steps.mode.outputs.mode }}\`" >> $GITHUB_STEP_SUMMARY
          echo "**Validation Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> $GITHUB_STEP_SUMMARY
          echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY

          echo "### Code Coverage" >> $GITHUB_STEP_SUMMARY
          if [ -f ../cloudforge-api/target/site/jacoco/index.html ]; then
            API_COVERAGE=$(grep "Total" ../cloudforge-api/target/site/jacoco/index.html | grep -o '[0-9][0-9]*%' | head -1 | tr -d '%' || echo "N/A")
            echo "- **cloudforge-api:** ${API_COVERAGE}% instruction coverage" >> $GITHUB_STEP_SUMMARY
          fi
          if [ -f ../cloudforge-core/target/site/jacoco/index.html ]; then
            CORE_COVERAGE=$(grep "Total" ../cloudforge-core/target/site/jacoco/index.html | grep -o '[0-9][0-9]*%' | head -1 | tr -d '%' || echo "N/A")
            echo "- **cloudforge-core:** ${CORE_COVERAGE}% instruction coverage" >> $GITHUB_STEP_SUMMARY
          fi
          echo "" >> $GITHUB_STEP_SUMMARY

          # Check for truth table results
          if [ -f scripts/validation-results/truth-table.json ]; then
            echo "### Configuration Analysis" >> $GITHUB_STEP_SUMMARY
            TOTAL=$(jq -r '.metadata.total_configurations // 0' scripts/validation-results/truth-table.json)
            VALID=$(jq -r '.metadata.valid_configurations // 0' scripts/validation-results/truth-table.json)
            INVALID=$(jq -r '.metadata.invalid_configurations // 0' scripts/validation-results/truth-table.json)

            echo "| Metric | Count |" >> $GITHUB_STEP_SUMMARY
            echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
            echo "| Total Configurations | $TOTAL |" >> $GITHUB_STEP_SUMMARY
            echo "| Valid Configurations | $VALID |" >> $GITHUB_STEP_SUMMARY
            echo "| Invalid Combinations | $INVALID |" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
          fi

          # Check for validation results
          if [ -d scripts/validation-results/current ] && [ "$(ls -A scripts/validation-results/current/*.json 2>/dev/null)" ]; then
            echo "### Validation Results" >> $GITHUB_STEP_SUMMARY
            PASSED=0
            FAILED=0

            for file in scripts/validation-results/current/*-validation.json; do
              if [ -f "$file" ]; then
                STATUS=$(jq -r '.summary.status // "UNKNOWN"' "$file")
                if [ "$STATUS" == "PASS" ]; then
                  PASSED=$((PASSED + 1))
                else
                  FAILED=$((FAILED + 1))
                fi
              fi
            done

            TOTAL=$((PASSED + FAILED))
            echo "- **Total Tests:** $TOTAL" >> $GITHUB_STEP_SUMMARY
            echo "- **Passed:** $PASSED ✅" >> $GITHUB_STEP_SUMMARY
            echo "- **Failed:** $FAILED ❌" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
          fi

          # Check for drift detection
          LATEST_DRIFT=$(ls -t scripts/validation-results/drift-reports/drift-summary-*.txt 2>/dev/null | head -1)
          if [ -f "$LATEST_DRIFT" ]; then
            echo "### Drift Detection" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            head -20 "$LATEST_DRIFT" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
          fi

          # Add testing strategy for PRs
          if [ -f testing-strategy.txt ]; then
            echo "### Testing Strategy" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            cat testing-strategy.txt >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
          fi

          # Overall status
          if [ "${{ steps.validation.outputs.exit_code }}" == "0" ]; then
            echo "### ✅ Validation Passed" >> $GITHUB_STEP_SUMMARY
          else
            echo "### ❌ Validation Failed" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
            echo "Please review the validation artifacts for detailed error information." >> $GITHUB_STEP_SUMMARY
          fi

          echo "" >> $GITHUB_STEP_SUMMARY
          echo "---" >> $GITHUB_STEP_SUMMARY
          echo "*Artifacts containing detailed validation results are available for download.*" >> $GITHUB_STEP_SUMMARY

      - name: Comment validation results on PR
        if: github.event_name == 'pull_request' && always()
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const exitCode = '${{ steps.validation.outputs.exit_code }}';
            const mode = '${{ steps.mode.outputs.mode }}';

            let comment = '## 🧪 CFC Validation Results\n\n';
            comment += `**Mode:** \`${mode}\`\n`;
            comment += `**Status:** ${exitCode === '0' ? '✅ Passed' : '❌ Failed'}\n\n`;

            // Add testing strategy if available
            try {
              const strategy = fs.readFileSync('cfc-testing/testing-strategy.txt', 'utf8');
              if (strategy && !strategy.includes('No Java/TypeScript files changed')) {
                comment += '### 🎯 Testing Strategy\n\n';
                comment += '```\n' + strategy + '\n```\n\n';
              }
            } catch (e) {
              console.log('No testing strategy available');
            }

            comment += '### 📊 Details\n\n';
            comment += 'Full validation results are available in the workflow artifacts.\n\n';

            if (exitCode !== '0') {
              comment += '⚠️ **Action Required:** Please review the validation failures and update your changes accordingly.\n\n';
            }

            comment += `[View Full Workflow Results](${context.payload.pull_request.html_url}/checks)\n`;

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            });

      - name: Check validation status
        if: steps.validation.outputs.exit_code != '0' && github.event_name != 'pull_request'
        run: |
          echo "Validation failed with exit code: ${{ steps.validation.outputs.exit_code }}"
          echo "Please review the validation artifacts for details."
          exit 1
