// =============================================================================
// RepoLens Jenkins Pipeline Template
// =============================================================================
//
// This template provides a ready-to-use Jenkins declarative pipeline for
// running RepoLens audits on your repository.
//
// USAGE:
// 1. Copy this file to your repository root as `Jenkinsfile`
// 2. Customize the environment variables and settings as needed
// 3. Configure a Jenkins pipeline job pointing to this file
//
// REQUIREMENTS:
// - Jenkins with Pipeline plugin installed
// - Docker available on Jenkins agents (for Docker approach)
// - OR: RepoLens binary installed on agents
//
// =============================================================================

pipeline {
    // Agent configuration - use Docker or a labeled agent
    agent {
        docker {
            // Use the official RepoLens Docker image
            image 'ghcr.io/delfour-co/repolens:latest'
            // Mount workspace for file access
            args '-v ${WORKSPACE}:/workspace -w /workspace'
        }
    }

    // Alternative: Use a specific agent label
    // agent { label 'linux' }

    // Environment variables
    environment {
        // RepoLens configuration
        REPOLENS_VERSION = 'latest'
        REPOLENS_PRESET = 'opensource'
        REPOLENS_FORMAT = 'json'
        REPOLENS_FAIL_ON = 'critical'

        // Report output directory
        REPORT_DIR = 'repolens-reports'
    }

    // Pipeline options
    options {
        // Discard old builds
        buildDiscarder(logRotator(numToKeepStr: '10'))
        // Timeout for the entire pipeline
        timeout(time: 30, unit: 'MINUTES')
        // Add timestamps to console output
        timestamps()
        // Don't run concurrent builds on the same branch
        disableConcurrentBuilds()
    }

    // Pipeline parameters (can be customized when triggering builds)
    parameters {
        choice(
            name: 'PRESET',
            choices: ['opensource', 'enterprise', 'strict'],
            description: 'RepoLens audit preset'
        )
        choice(
            name: 'FORMAT',
            choices: ['json', 'sarif', 'html', 'markdown', 'terminal'],
            description: 'Report output format'
        )
        choice(
            name: 'FAIL_ON',
            choices: ['critical', 'high', 'medium', 'low', 'none'],
            description: 'Fail build on severity level'
        )
        booleanParam(
            name: 'SKIP_AUDIT',
            defaultValue: false,
            description: 'Skip the audit (for debugging pipeline)'
        )
    }

    stages {
        // =================================================================
        // Stage: Setup
        // =================================================================
        stage('Setup') {
            steps {
                script {
                    // Create report directory
                    sh "mkdir -p ${REPORT_DIR}"

                    // Display RepoLens version
                    sh 'repolens --version'
                }
            }
        }

        // =================================================================
        // Stage: Audit
        // =================================================================
        stage('Audit') {
            when {
                expression { return !params.SKIP_AUDIT }
            }
            steps {
                script {
                    // Determine preset and format from parameters
                    def preset = params.PRESET ?: env.REPOLENS_PRESET
                    def format = params.FORMAT ?: env.REPOLENS_FORMAT
                    def failOn = params.FAIL_ON ?: env.REPOLENS_FAIL_ON

                    // Determine file extension
                    def ext = 'txt'
                    switch(format) {
                        case 'json': ext = 'json'; break
                        case 'sarif': ext = 'sarif'; break
                        case 'html': ext = 'html'; break
                        case 'markdown': ext = 'md'; break
                    }

                    def reportFile = "${REPORT_DIR}/audit-report.${ext}"

                    // Run RepoLens audit
                    def exitCode = sh(
                        script: """
                            repolens plan \
                                --preset ${preset} \
                                --format ${format} \
                                --output ${reportFile}
                        """,
                        returnStatus: true
                    )

                    // Store exit code for later use
                    env.AUDIT_EXIT_CODE = exitCode.toString()

                    // Handle failure based on fail-on setting
                    if (failOn != 'none' && exitCode != 0) {
                        if (failOn == 'critical' && exitCode == 1) {
                            error("Critical findings detected in audit")
                        } else if (failOn in ['high', 'medium', 'low']) {
                            error("Findings detected at or above '${failOn}' severity")
                        }
                    }
                }
            }
        }

        // =================================================================
        // Stage: Generate Additional Reports
        // =================================================================
        stage('Generate Reports') {
            parallel {
                // Generate JSON report for programmatic access
                stage('JSON Report') {
                    when {
                        expression { return params.FORMAT != 'json' }
                    }
                    steps {
                        sh """
                            repolens plan \
                                --preset ${params.PRESET ?: env.REPOLENS_PRESET} \
                                --format json \
                                --output ${REPORT_DIR}/audit-report.json
                        """
                    }
                }

                // Generate HTML report for human-readable output
                stage('HTML Report') {
                    when {
                        expression { return params.FORMAT != 'html' }
                    }
                    steps {
                        sh """
                            repolens plan \
                                --preset ${params.PRESET ?: env.REPOLENS_PRESET} \
                                --format html \
                                --output ${REPORT_DIR}/audit-report.html
                        """
                    }
                }
            }
        }
    }

    // Post-build actions
    post {
        always {
            // Archive all reports
            archiveArtifacts(
                artifacts: "${REPORT_DIR}/**/*",
                allowEmptyArchive: true,
                fingerprint: true
            )

            // Publish HTML report (requires HTML Publisher plugin)
            publishHTML(target: [
                allowMissing: true,
                alwaysLinkToLastBuild: true,
                keepAll: true,
                reportDir: "${REPORT_DIR}",
                reportFiles: 'audit-report.html',
                reportName: 'RepoLens Audit Report',
                reportTitles: 'RepoLens Audit'
            ])

            // Clean up workspace
            cleanWs(
                cleanWhenNotBuilt: false,
                deleteDirs: true,
                disableDeferredWipeout: true,
                notFailBuild: true,
                patterns: [[pattern: '.repolens/cache/**', type: 'EXCLUDE']]
            )
        }

        success {
            echo 'RepoLens audit completed successfully!'
        }

        failure {
            echo 'RepoLens audit found critical issues!'

            // Optional: Send notification on failure
            // emailext(
            //     subject: "RepoLens Audit Failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
            //     body: "Audit report: ${env.BUILD_URL}artifact/${REPORT_DIR}/audit-report.html",
            //     recipientProviders: [developers(), requestor()]
            // )
        }

        unstable {
            echo 'RepoLens audit found warnings.'
        }
    }
}

// =============================================================================
// Alternative: Binary Installation Pipeline
// =============================================================================
// Use this pipeline if Docker is not available on your Jenkins agents.
//
// Uncomment and modify as needed:
//
// pipeline {
//     agent { label 'linux' }
//
//     environment {
//         REPOLENS_VERSION = 'latest'
//         PATH = "/usr/local/bin:${env.PATH}"
//     }
//
//     stages {
//         stage('Install RepoLens') {
//             steps {
//                 script {
//                     def version = env.REPOLENS_VERSION
//                     if (version == 'latest') {
//                         version = sh(
//                             script: 'curl -s https://api.github.com/repos/delfour-co/cli--repolens/releases/latest | grep tag_name | sed -E "s/.*\\"v([^\\"]+)\\".*/\\1/"',
//                             returnStdout: true
//                         ).trim()
//                     }
//
//                     sh """
//                         curl -LO "https://github.com/delfour-co/cli--repolens/releases/download/v${version}/repolens-linux-x86_64.tar.gz"
//                         tar xzf repolens-linux-x86_64.tar.gz
//                         sudo mv repolens /usr/local/bin/
//                         rm repolens-linux-x86_64.tar.gz
//                         repolens --version
//                     """
//                 }
//             }
//         }
//
//         stage('Audit') {
//             steps {
//                 sh 'repolens plan --format json --output audit-report.json'
//             }
//         }
//     }
//
//     post {
//         always {
//             archiveArtifacts artifacts: '*.json', allowEmptyArchive: true
//         }
//     }
// }

// =============================================================================
// Scripted Pipeline Alternative
// =============================================================================
// For more complex requirements, use a scripted pipeline:
//
// node('docker') {
//     stage('Checkout') {
//         checkout scm
//     }
//
//     docker.image('ghcr.io/delfour-co/repolens:latest').inside {
//         stage('Audit') {
//             sh 'repolens plan --format json --output audit-report.json'
//         }
//     }
//
//     stage('Archive') {
//         archiveArtifacts artifacts: '*.json'
//     }
// }
