// Jenkinsfile CI/CD Pipeline for Test Execution
// Generated by BMad TEA Agent - Test Architect Module
// Optimized for: Parallel Sharding, Burn-In Loop
// Stack: {test_stack_type} | Framework: {test_framework}
//
// Variables to customize per project:
//   INSTALL_CMD       - dependency install command (e.g., npm ci, pnpm install --frozen-lockfile)
//   TEST_CMD          - main test command (e.g., npm run test:e2e, npm test, npx vitest)
//   LINT_CMD          - lint command (e.g., npm run lint)
//   BROWSER_INSTALL   - browser install command (frontend/fullstack only; omit for backend)
//
// Node.js version management — choose one:
//   Option A (recommended): Configure NodeJS Plugin in Jenkins Global Tool Configuration,
//     then add to pipeline:  tools { nodejs 'NodeJS-24' }
//   Option B: Use nvm (pre-installed on agent) — this template uses nvm as the default
//   Option C: Use a Docker agent — agent { docker { image 'node:24' } }

pipeline {
    agent any

    environment {
        CI = 'true'
    }

    options {
        timeout(time: 45, unit: 'MINUTES')
        disableConcurrentBuilds()
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install') {
            steps {
                // Detect and apply Node.js version from .nvmrc (falls back to v24)
                // If using NodeJS Plugin instead, remove this block and add: tools { nodejs 'NodeJS-24' }
                sh '''
                    export NVM_DIR="$HOME/.nvm"
                    [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
                    NODE_VERSION=$(cat .nvmrc 2>/dev/null || echo "24")
                    nvm install "$NODE_VERSION" 2>/dev/null || true
                    nvm use "$NODE_VERSION" 2>/dev/null || true
                    node --version
                    npm ci
                ''' // Replace npm ci with INSTALL_CMD
                // Stash installed dependencies so parallel shards can restore them
                stash includes: 'node_modules/**', name: 'deps'
            }
        }

        stage('Lint') {
            steps {
                sh 'npm run lint' // Replace with LINT_CMD
            }
        }

        // Test stage - Parallel execution with sharding
        // Each shard restores dependencies via unstash for workspace safety
        stage('Test') {
            parallel {
                stage('Shard 1') {
                    steps {
                        unstash 'deps'
                        // Frontend/Fullstack only — remove browser install for backend-only stacks
                        sh 'npx playwright install --with-deps chromium' // Replace with BROWSER_INSTALL
                        sh 'npm run test:e2e -- --shard=1/4' // Replace with TEST_CMD + shard args
                    }
                }
                stage('Shard 2') {
                    steps {
                        unstash 'deps'
                        sh 'npx playwright install --with-deps chromium' // Replace with BROWSER_INSTALL
                        sh 'npm run test:e2e -- --shard=2/4' // Replace with TEST_CMD + shard args
                    }
                }
                stage('Shard 3') {
                    steps {
                        unstash 'deps'
                        sh 'npx playwright install --with-deps chromium' // Replace with BROWSER_INSTALL
                        sh 'npm run test:e2e -- --shard=3/4' // Replace with TEST_CMD + shard args
                    }
                }
                stage('Shard 4') {
                    steps {
                        unstash 'deps'
                        sh 'npx playwright install --with-deps chromium' // Replace with BROWSER_INSTALL
                        sh 'npm run test:e2e -- --shard=4/4' // Replace with TEST_CMD + shard args
                    }
                }
            }
        }

        // Burn-in stage - Flaky test detection
        // Note: Burn-in targets UI flakiness. For backend-only stacks, remove this stage entirely.
        stage('Burn-In') {
            when {
                anyOf {
                    changeRequest()
                    triggeredBy 'TimerTrigger'
                }
            }
            steps {
                sh '''
                    echo "Starting burn-in loop - detecting flaky tests"
                    for i in $(seq 1 10); do
                        echo "Burn-in iteration $i/10"
                        npm run test:e2e || exit 1
                    done
                    echo "Burn-in complete - no flaky tests detected"
                ''' // Replace npm run test:e2e with TEST_CMD
            }
        }
    }

    post {
        always {
            // Archive test results and reports
            archiveArtifacts artifacts: 'test-results/**,playwright-report/**', allowEmptyArchive: true
            junit testResults: 'test-results/**/*.xml', allowEmptyResults: true
        }
        failure {
            echo 'Pipeline failed - check test results and artifacts'
        }
    }
}
