// Declarative Pipeline - Modern Jenkins Syntax
// Jenkins 2.440+ LTS Compatible
//
// This is the recommended syntax for Jenkins pipelines.
// Declarative pipelines are easier to read, write, and maintain.

pipeline {
    // Agent configuration - where the pipeline will execute
    agent {
        // Use Docker agent for consistent, reproducible builds
        docker {
            image 'node:18-alpine'
            // Mount Docker socket for Docker-in-Docker operations (if needed)
            // args '-v /var/run/docker.sock:/var/run/docker.sock'
        }
        // Alternative: Use Kubernetes agent
        // kubernetes {
        //     yaml '''
        //     apiVersion: v1
        //     kind: Pod
        //     spec:
        //       containers:
        //       - name: node
        //         image: node:18-alpine
        //         command: ['cat']
        //         tty: true
        //     '''
        // }
        // Alternative: Use any available agent
        // agent any
    }

    // Environment variables available to all stages
    environment {
        // Application settings
        APP_NAME = 'my-application'
        APP_VERSION = "${env.BUILD_NUMBER}"

        // Docker registry (if using Docker)
        DOCKER_REGISTRY = 'docker.io'
        DOCKER_IMAGE = "${DOCKER_REGISTRY}/myorg/${APP_NAME}"

        // Credentials (stored in Jenkins credentials store)
        DOCKER_CREDENTIALS = credentials('docker-hub-credentials')
        AWS_CREDENTIALS = credentials('aws-credentials')

        // Build settings
        NODE_ENV = 'production'
        CI = 'true'
    }

    // Build parameters (configurable at runtime)
    parameters {
        string(
            name: 'BRANCH_NAME',
            defaultValue: 'main',
            description: 'Git branch to build'
        )
        choice(
            name: 'DEPLOY_ENVIRONMENT',
            choices: ['dev', 'staging', 'production'],
            description: 'Target deployment environment'
        )
        booleanParam(
            name: 'RUN_TESTS',
            defaultValue: true,
            description: 'Run test suite'
        )
        booleanParam(
            name: 'SKIP_DEPLOY',
            defaultValue: false,
            description: 'Skip deployment stage'
        )
    }

    // Build options
    options {
        // Keep only last 10 builds
        buildDiscarder(logRotator(numToKeepStr: '10'))

        // Timeout entire pipeline after 1 hour
        timeout(time: 1, unit: 'HOURS')

        // Disable concurrent builds
        disableConcurrentBuilds()

        // Timestamp console output
        timestamps()

        // Add ANSI color to console output
        ansiColor('xterm')
    }

    // SCM polling triggers
    triggers {
        // Poll SCM every 5 minutes (use webhooks in production)
        pollSCM('H/5 * * * *')

        // Cron-based trigger (nightly builds)
        cron('H 2 * * *')
    }

    stages {
        stage('Checkout') {
            steps {
                echo "Checking out code from ${params.BRANCH_NAME}..."

                // Checkout code from Git
                checkout scm

                // Display git commit info
                script {
                    env.GIT_COMMIT_MSG = sh(
                        script: 'git log -1 --pretty=%B',
                        returnStdout: true
                    ).trim()
                    env.GIT_COMMIT_AUTHOR = sh(
                        script: 'git log -1 --pretty=%an',
                        returnStdout: true
                    ).trim()
                }

                echo "Latest commit: ${env.GIT_COMMIT_MSG}"
                echo "Author: ${env.GIT_COMMIT_AUTHOR}"
            }
        }

        stage('Install Dependencies') {
            steps {
                echo 'Installing dependencies...'
                sh 'npm ci --prefer-offline --no-audit'
            }
        }

        stage('Code Quality') {
            // Run in parallel for faster execution
            parallel {
                stage('Lint') {
                    steps {
                        echo 'Running linter...'
                        sh 'npm run lint'
                    }
                }

                stage('Format Check') {
                    steps {
                        echo 'Checking code format...'
                        sh 'npm run format:check'
                    }
                }

                stage('Type Check') {
                    steps {
                        echo 'Running type checker...'
                        sh 'npm run type-check'
                    }
                }
            }
        }

        stage('Test') {
            when {
                expression { params.RUN_TESTS == true }
            }
            steps {
                echo 'Running test suite...'
                sh 'npm run test:ci'
            }
            post {
                always {
                    // Publish test results
                    junit 'test-results/**/*.xml'

                    // Publish coverage reports
                    publishHTML([
                        allowMissing: false,
                        alwaysLinkToLastBuild: true,
                        keepAll: true,
                        reportDir: 'coverage',
                        reportFiles: 'index.html',
                        reportName: 'Coverage Report'
                    ])
                }
            }
        }

        stage('Security Scan') {
            parallel {
                stage('Dependency Audit') {
                    steps {
                        echo 'Auditing dependencies for vulnerabilities...'
                        sh 'npm audit --audit-level=moderate'
                    }
                }

                stage('SAST Scan') {
                    steps {
                        echo 'Running static application security testing...'
                        // Example with SonarQube
                        // sh 'sonar-scanner'
                        echo 'SAST scan would run here'
                    }
                }
            }
        }

        stage('Build') {
            steps {
                echo 'Building application...'
                sh 'npm run build'
            }
            post {
                success {
                    // Archive build artifacts
                    archiveArtifacts artifacts: 'dist/**/*', fingerprint: true
                }
            }
        }

        stage('Build Docker Image') {
            steps {
                script {
                    echo "Building Docker image: ${DOCKER_IMAGE}:${APP_VERSION}"

                    // Build Docker image
                    sh """
                        docker build \
                            --tag ${DOCKER_IMAGE}:${APP_VERSION} \
                            --tag ${DOCKER_IMAGE}:latest \
                            --build-arg BUILD_NUMBER=${env.BUILD_NUMBER} \
                            --build-arg GIT_COMMIT=${env.GIT_COMMIT} \
                            .
                    """
                }
            }
        }

        stage('Push Docker Image') {
            steps {
                script {
                    echo 'Pushing Docker image to registry...'

                    // Login to Docker registry
                    sh "echo ${DOCKER_CREDENTIALS_PSW} | docker login -u ${DOCKER_CREDENTIALS_USR} --password-stdin ${DOCKER_REGISTRY}"

                    // Push image
                    sh "docker push ${DOCKER_IMAGE}:${APP_VERSION}"
                    sh "docker push ${DOCKER_IMAGE}:latest"
                }
            }
        }

        stage('Deploy') {
            when {
                expression { params.SKIP_DEPLOY == false }
            }
            steps {
                script {
                    echo "Deploying to ${params.DEPLOY_ENVIRONMENT}..."

                    // Example deployment commands
                    if (params.DEPLOY_ENVIRONMENT == 'production') {
                        // Require manual approval for production
                        input message: 'Deploy to production?', ok: 'Deploy'
                    }

                    // Deploy (example with kubectl)
                    sh """
                        kubectl set image deployment/${APP_NAME} \
                            ${APP_NAME}=${DOCKER_IMAGE}:${APP_VERSION} \
                            -n ${params.DEPLOY_ENVIRONMENT}
                    """

                    // Wait for rollout
                    sh """
                        kubectl rollout status deployment/${APP_NAME} \
                            -n ${params.DEPLOY_ENVIRONMENT} \
                            --timeout=5m
                    """
                }
            }
        }

        stage('Integration Tests') {
            when {
                expression { params.SKIP_DEPLOY == false }
            }
            steps {
                echo 'Running integration tests against deployed environment...'
                sh 'npm run test:integration'
            }
        }
    }

    // Post-build actions (run after all stages)
    post {
        always {
            echo 'Pipeline completed!'

            // Clean workspace
            cleanWs()

            // Send notifications
            script {
                def status = currentBuild.result ?: 'SUCCESS'
                def color = status == 'SUCCESS' ? 'good' : 'danger'

                // Example: Slack notification
                // slackSend(
                //     color: color,
                //     message: "Build ${env.BUILD_NUMBER} ${status}: ${env.JOB_NAME}"
                // )
            }
        }

        success {
            echo 'Build succeeded!'
            // Additional success actions
        }

        failure {
            echo 'Build failed!'
            // Send failure notifications
            // Create incident ticket
        }

        unstable {
            echo 'Build is unstable'
            // Handle unstable builds
        }

        changed {
            echo 'Build status changed from previous build'
        }
    }
}
