@Library('nf-jenkins-shared-libraries')_  

JAVA_HOME='/opt/java/openjdk'
MVN_HOME='mvn_local_repository'
REPO='core-management'
ECR_TAG=""
BUILD_LINK=""

s_version=""
link_url = ""

channel = "cd-mop-staging"
skip_dependency = "false"

pipeline {
    agent {
        ecs {
            inheritFrom 'agent-jdk17'
            cpu 4096
            memoryReservation 16384
        }
    }

    environment {
        DOCKER_HUB = credentials('nfdockerhub')
        ARTIFACTORY = credentials('jfrog-mop-reader')
        SONAR_CLOUD = credentials('sonar')
        BITBUCKET_AUTH = credentials('bitbucket_auth')
    }

    parameters {
        choice(name: 'IMAGE_TYPE', choices: ['sandbox', 'release', 'hotfix'], description: 'Whether the image is to be a release for prod or a release candidate for lower environments')
        string(name: 'BRANCH', defaultValue: 'develop', description: 'Branch to be built from')
    }

    stages {
        stage('Checkout Branch') {
            steps {
                git credentialsId: 'new-jenkins-bitbucket-ssh', url: "git@bitbucket.org:netfoundry/${REPO}.git", branch: "${params.BRANCH}"
                sh "ls"
                script {
                    GIT_HASH = sh(returnStdout: true, script: "git rev-parse --short HEAD").trim()
                }
                echo "hash is: ${GIT_HASH}"
            }
        }

        stage('Maven Build'){
            steps{
                script{
                    sh "mkdir -p ${MVN_HOME}/${BUILD_NUMBER}"
                }
                script {
                    configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                        s_version = sh(script: "./mvnw -s $MAVEN_SETTINGS_XML org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version -q -DforceStdout | grep SNAPSHOT", returnStdout: true).trim()
                        s_version = s_version.split("-")[0]
                        sh """
                        export JAVA_HOME=${JAVA_HOME}
                        export SPRING_PROFILES_ACTIVE=test
                        ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 clean
                        ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 -DskipTests compile test-compile
                        """
                    }
                }
            }
        }


        stage('Maven Tests') {
            parallel {
                stage('Baseline Tests') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                export SPRING_PROFILES_ACTIVE=test
                                ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 -Ptest \
                                -Dtest.redis.port=6400 -Dlogging.level.io.netfoundry=warn -Dlogging.level.io.netfoundry.core=info -Dlogging.level.io.netfoundry.common=info -Dlogging.level.org.springframework=warn \
                                test -Dgroups=\"!validation & !find & !controller_common & !controller_v2 & !controller_v3 & !process\"
                                """
                            }
                        }
                    }
                }

                stage('Validation Tests') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                export SPRING_PROFILES_ACTIVE=test
                                ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 -Ptest \
                                -Dtest.redis.port=6404 -Dlogging.level.io.netfoundry=warn -Dlogging.level.io.netfoundry.core=info -Dlogging.level.io.netfoundry.common=info -Dlogging.level.org.springframework=warn \
                                test -Dgroups=\"validation\"
                                """
                            }
                        }
                    }
                }

                stage('Controller Tests (Common)') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                export SPRING_PROFILES_ACTIVE=test
                                ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 -Ptest \
                                -Dtest.redis.port=6401 -Dlogging.level.io.netfoundry=warn -Dlogging.level.io.netfoundry.core=info -Dlogging.level.io.netfoundry.common=info -Dlogging.level.org.springframework=warn \
                                test -Dgroups=\"controller_common\"
                                """
                            }
                        }
                    }
                }

                stage('Controller Tests (V2)') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                export SPRING_PROFILES_ACTIVE=test
                                ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 -Ptest \
                                -Dtest.redis.port=6402 -Dlogging.level.io.netfoundry=warn -Dlogging.level.io.netfoundry.core=info -Dlogging.level.io.netfoundry.common=info -Dlogging.level.org.springframework=warn \
                                test -Dgroups=\"controller_v2\"
                                """
                            }
                        }
                    }
                }

                stage('Controller Tests (V3)') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                export SPRING_PROFILES_ACTIVE=test
                                ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 -Ptest \
                                -Dtest.redis.port=6403 -Dlogging.level.io.netfoundry=warn -Dlogging.level.io.netfoundry.core=info -Dlogging.level.io.netfoundry.common=info -Dlogging.level.org.springframework=warn \
                                test -Dgroups=\"controller_v3\"
                                """
                            }
                        }
                    }
                }

                stage('Find Tests') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                export SPRING_PROFILES_ACTIVE=test
                                ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 -Ptest \
                                -Dtest.redis.port=6405 -Dlogging.level.io.netfoundry=warn -Dlogging.level.io.netfoundry.core=info -Dlogging.level.io.netfoundry.common=info -Dlogging.level.org.springframework=warn \
                                test -Dgroups=\"find\"
                                """
                            }
                        }
                    }
                }

                stage('Process Tests') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                export SPRING_PROFILES_ACTIVE=test
                                ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -T 8 -Ptest \
                                -Dtest.redis.port=6406 -Dlogging.level.io.netfoundry=warn -Dlogging.level.io.netfoundry.core=info -Dlogging.level.io.netfoundry.common=info -Dlogging.level.org.springframework=warn \
                                test -Dgroups=\"process\"
                                """
                            }
                        }
                    }
                }
            }
        }


        stage('Docs & Dependencies') {
            parallel {
                stage('Docs') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                ./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -Pdocs -DskipTests verify
                                """
                            }
                        }
                    }
                }

                stage('OpenApi Client') {
                    steps {
                        script {
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh """
                                ./mvnw -s $MAVEN_SETTINGS_XML resources:resources generate-sources -PcoreClient
                                ./mvnw -s $MAVEN_SETTINGS_XML -f target/client/pom.xml -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} install
                                ./mvnw -s $MAVEN_SETTINGS_XML -f target/admin-client/pom.xml -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} install
                                """
                            }
                        }
                    }
                }

                stage('Sonar & Dependencies') {
                    when { expression { "${params.BRANCH}" == "develop" }}
                    steps {
                        script {
                            try{
                                configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                    sh "./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -Pdependency_check -DskipTests dependency-check:check xml:transform"
                                }
                            }catch(e){
                                skip_dependency = "true"
                                echo "Dependency Checks failed with error ${e}"
                                fn_msg = "Dependency Checks failed. The build will still continue. Please check link for details."
                                color = "#FF8000"
                                author_email = fetch_author_email("${REPO}", "${GIT_HASH}")
                                send_custom_notification("${author_email}", "${REPO}", "${channel}", "${fn_msg}", "${color}", "${link_url}")
                            }
                        }
                        script {
                            //generate jacoco report
                            configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                                sh "./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -Ptest -DskipTests verify"
                            }

                            //sonar analysis
                            sonar_project_name = "${REPO}"
                            check_sonar_with_dependency_mvnw BRANCH: "${params.BRANCH}", PROJECT_NAME: "${sonar_project_name}", JAVA_HOME: JAVA_HOME, MAVEN_HOME: "${MVN_HOME}/${BUILD_NUMBER}", skipTests: true
                        }
                    }
                }
            }
        }

        stage('Archive Artifacts'){
            steps{
                script {
                    archiveArtifacts "target/*.*"
                }
            }
        }

        stage('JUnit Reports') {
            when { expression { "${params.BRANCH}" == "develop" }}
            steps {
                script {
                    junitParse services: [REPO], parallelize: false, dir: "", xml: "target/surefire-reports/*.xml"
                }
            }
        }

        stage('Artifactory') {
            when { expression { "${params.BRANCH}" == "develop" }}
            steps {
                script {
                    artifactory_mvnw POM_FILE: "target/client/pom.xml", REPO: "${REPO}-client",  BUILDPATH: "${MVN_HOME}/${BUILD_NUMBER}"
                }
            }
        }

        stage('Closure'){
            steps{
                script{
                    def tag_suffix = "${new Date().format('yyyyMMddHHmm')}"
                    ECR_TAG = "${GIT_HASH}-${IMAGE_TYPE}-${tag_suffix}"
                    currentBuild.description = "Git Hash: ${GIT_HASH}\n ECR Tag: ${ECR_TAG}"
                }
            }
        }
    }

    post {
        always {
            script {
                sh "rm -rf ${MVN_HOME}/${BUILD_NUMBER}"
                env.BUILD_LINK = "${RUN_DISPLAY_URL}"
            }
        }
        success {
            script {
                env.ECR_TAG = "${ECR_TAG}"
                env.S_VERSION = "${s_version}"
                env.SKIP_DEPENDENCY = "${skip_dependency}"
            }
        }
    }
}