String SLACK_NOTIFICATIONS_CHANNEL = '#dx-alerts'
String MAVEN_IMAGE_REPO = 'maven'
String MAVEN_IMAGE_TAG = '3.9-eclipse-temurin-17'

pipeline {
    agent any

    parameters {
        choice(name: 'PACKAGE_NAMES', choices: ['dx-persistence'], description: 'Select which packages to build and publish')
        string(name: 'SHARED_LIBRARIES_VERSION', defaultValue: 'master', description: 'The version of the Jenkins shared libraries to use. Can be a branch, tag or Git revision.')
    }

    stages {
        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }

        stage('Validate Software Catalog Definition') {
            steps {
                withModifiedFunctions(checkout: true) { packageName -> 
                    datadogSoftwareCatalogValidate(servicePath: "${packageName}")
                }
            }
        }

        stage('Build and Test') {
            steps {
                withModifiedFunctions(checkout: true) { packageName -> 
                    echo "Building and testing ${packageName}..."
                    dockerRun(
                        imageRepo: MAVEN_IMAGE_REPO,
                        imageTag: MAVEN_IMAGE_TAG,
                        script: 'mvn clean package',
                        workdir: "/workspace/${packageName}",
                        volumes: [
                            "${env.WORKSPACE}:/workspace",
                            "maven-repo:/root/.m2/repository"
                        ]
                    )
                }
            }
            post {
                always {
                    junit allowEmptyResults: true, testResults: '**/target/surefire-reports/*.xml'
                }
            }
        }

        stage('Publish') {
            when {
                anyOf {
                    branch 'master'
                }
            }
            steps {
                withCredentials([
                    string(credentialsId: 'github_packages_token', variable: 'GITHUB_TOKEN'),
                    string(credentialsId: 'github_packages_username', variable: 'GITHUB_USERNAME')
                ]) {
                    withModifiedFunctions(checkout: true) { packageName ->
                        echo "Publishing ${packageName} to GitHub Packages..."
                        dockerRun(
                            imageRepo: MAVEN_IMAGE_REPO,
                            imageTag: MAVEN_IMAGE_TAG,
                            script: 'mvn deploy -DskipTests --settings /workspace/settings.xml',
                            workdir: "/workspace/${packageName}",
                            volumes: [
                                "${env.WORKSPACE}:/workspace",
                                "maven-repo:/root/.m2/repository"
                            ],
                            envVars: [
                                GITHUB_TOKEN: env.GITHUB_TOKEN,
                                GITHUB_USERNAME: env.GITHUB_USERNAME
                            ]
                        )
                        datadogSoftwareCatalogPublish(servicePath: "${packageName}")
                    }
                }
            }
        }
    }

    post {
        regression {
            script {
                if (env.BRANCH_NAME == 'master') {
                    slackNotify channel: SLACK_NOTIFICATIONS_CHANNEL
                }
            }
        }
        fixed {
            script {
                if (env.BRANCH_NAME == 'master') {
                    slackNotify channel: SLACK_NOTIFICATIONS_CHANNEL
                }
            }
        }
        cleanup {
            cleanWs()
        }
    }
}

def withModifiedFunctions(Map args = [:], Closure steps) {
    getMonorepoUtils().withModifiedProjects(args, steps)
}

def getMonorepoUtils() {
    return library("jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}").com.sonymusic.MonorepoUtils.getInstance(
        steps: this,
        projectBasePath: ".",
        projectsToBuild: params.PACKAGE_NAMES ? params.PACKAGE_NAMES.split(',') : null
    )
}
