@Library('nf-jenkins-shared-libraries@master')_
import org.apache.commons.lang3.StringUtils;
import jenkins.model.Jenkins
import hudson.model.*
import hudson.tasks.test.*
import groovy.xml.XmlUtil
import org.json.JSONObject
import org.json.XML

def bb_request, failure_reason, update_jenkins_build, channel

service_repo = []
IGNORE_TITLES = []
MVN_HOME = ""
BB_BRANCH = ""
COMMIT_HASH = ""
REPO = "reporting"

kibana_url = ""
smoketest_url = ""
artifact_link = ""
sonar_link = ""
failure_msg = ""
sandbox_image = ""
stage_name = ""

failure = false
blocking = true
send_notification = true
sonar_alert = false
killed_running_job = false
set_kibana_url = false
set_affected_service = false
set_smoketest_url = false
set_artifact_url = false
affected_service = null

pipeline {
    agent {
        ecs {
            inheritFrom 'agent-jdk17'
        }
    }

    environment {
        BITBUCKET_AUTH = credentials('bitbucket_auth')
        BITBUCKET_ADMIN = credentials('bitbucket_admin')
    }

    stages {
        stage('Initialize') {
            steps {
                script {
                    stage_name = env.STAGE_NAME
                    bb_request = readJSON text: bb_request_raw
                    REPO = bb_request.pullrequest.source.repository.full_name.split("/")[1]
                    BB_COMMENTS_URL="${bb_request.pullrequest.links.comments.href}"
                    BB_APPROVE_URL="${bb_request.pullrequest.links.approve.href}"
                    BB_DECLINE_URL="${bb_request.pullrequest.links.decline.href}"
                    BB_BRANCH="${bb_request.pullrequest.source.branch.name}"
                    BB_DESTINATION_BRANCH="${bb_request.pullrequest.destination.branch.name}"
                    COMMIT_HASH = "${bb_request.pullrequest.source.commit.hash}"
                    DESCRIPTION="Branch: ${BB_BRANCH} REPO: ${REPO}"

                    // Set Description
                    currentBuild.description = "${DESCRIPTION}"

                    //fetch constants
                    pr_const = readYaml text: libraryResource("pr_builds/const_vars.yaml")

                    MOP_LIBRARIES = pr_const["MOP_LIBRARIES"]
                    SONAR_EXEMPTION = pr_const["SONAR_EXEMPTION"]
                    MVN_HOME = pr_const["MVN_HOME"]
                    JAVA_HOME='/opt/java/openjdk'
                    CLUSTER_NAME = pr_const["CLUSTER_NAME"]
                    HELM_TIMEOUT = pr_const["HELM_TIMEOUT"]
                    helm_verbose_level = pr_const["helm_verbose_level"]
                    prenv = pr_const["prenv"]
                    channel = pr_const["channel"]
                    log_lines_capture = pr_const["log_lines_capture"]
                    update_jenkins_build = pr_const["update_jenkins_build"]

                    service_repo = readYaml text: libraryResource("pr_builds/service_repo_list.yaml")
                    IGNORE_TITLES = readYaml text: libraryResource("pr_builds/ignore_titles.yaml")

                    for(String ignoreStr: IGNORE_TITLES) {
                        if(bb_request.pullrequest.rendered.title.raw.toUpperCase().contains("${ignoreStr}")) {
                            failure_msg = "ignore"
                            send_notification = false
                            error "Build ignored as it starts with ${ignoreStr}"
                        }
                    }
                }
            }
        }

        stage('ChangeSet'){
            steps {
                script {
                    stage_name = env.STAGE_NAME
                    git_diff_serverless(REPO, BB_BRANCH)

                    // Check that destination branch
                    if(BB_DESTINATION_BRANCH != "develop") {
                        failure_msg = "ignore"
                        error "Only builds PR with destination branch as develop"
                    }
                    bitbucketStatus repo: "${REPO}", BRANCH_NAME: BB_BRANCH, GIT_COMMIT: COMMIT_HASH, status: "INPROGRESS", PR_CHECK: "false", BUILD_NAME: "Jenkins PR Build"
                }
            }
        }

        stage('Build') {
            steps {
                script {
                    stage_name = env.STAGE_NAME
                    configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                        sh "./mvnw -U -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} clean install"
                    }
                }
            }
        }
        
        stage('Dependency Checks') {
            steps {
                script {
                    stage_name = env.STAGE_NAME 
                    check_dependency_mvnw("${REPO}", "${REPO}", MOP_LIBRARIES)
                    configFileProvider([configFile(fileId: 'netfoundry_maven_settings', variable: 'MAVEN_SETTINGS_XML')]) {
                        sh "./mvnw -s $MAVEN_SETTINGS_XML -Dmaven.repo.local=${MVN_HOME}/${BUILD_NUMBER} -DskipTests dependency-check:check xml:transform"
                    }
                }
            }
        }

        stage('Sonar Quality Gate') {
            when { expression { newCheckAllowedServices(bb_request, SONAR_EXEMPTION, REPO) == true }}
            steps {
                script {
                    stage_name = env.STAGE_NAME
                    JAVA_HOME = "${JAVA_HOME}"
                    sonar_link = check_sonar_quality_gate_mvnw(bb_request, SONAR_EXEMPTION, REPO, BB_BRANCH, MVN_HOME, JAVA_HOME)
                    if( sonar_link != "") {
                        sonar_alert = true
                        error "Sonar Analysis failed. Link -> ${sonar_link}"
                    }
                }
            }
        }
    }

    post {
        always {
            script {
                echo "build completed"
                sh "rm -rf ${MVN_HOME}/${BUILD_NUMBER}"
            }
        }
        failure {
            script {
                failure_reason = "${stage_name} stage failed. ${failure_msg}"
                if (failure_msg != "ignore"){
                    bbReject(bb_request, REPO, BB_BRANCH, COMMIT_HASH, failure_reason, update_jenkins_build, affected_service, set_kibana_url, kibana_url, set_smoketest_url, smoketest_url, set_artifact_url, artifact_link, sonar_alert, sonar_link)
                }
                //Notification
                if(failure_msg != "ignore" && failure_msg != "org.jenkinsci.plugins.workflow.steps.FlowInterruptedException" && send_notification == true ){
                    pr_send_notification_message(bb_request, "${REPO}", failure_reason, channel, get_notification_links(bb_request, affected_service, set_kibana_url, kibana_url, set_smoketest_url, smoketest_url, set_artifact_url, artifact_link, sonar_alert, sonar_link))
                    currentBuild.rawBuild.@result = hudson.model.Result.FAILURE
                }
                if(failure_msg == "ignore") {
                    bitbucketStatus repo: "${REPO}", BRANCH_NAME: BB_BRANCH, GIT_COMMIT: COMMIT_HASH, status: "SUCCESSFUL", PR_CHECK: "false", BUILD_NAME: "Jenkins PR Build"
                    currentBuild.rawBuild.@result = hudson.model.Result.ABORTED
                }
            }
        }
        success {
            script {
                //Notification
                if (failure_msg != "ignore"){
                    bbApprove(bb_request, REPO, BB_BRANCH, COMMIT_HASH)
                }
                if(failure_msg == "ignore") {
                    bitbucketStatus repo: "${REPO}", BRANCH_NAME: BB_BRANCH, GIT_COMMIT: COMMIT_HASH, status: "SUCCESSFUL", PR_CHECK: "false", BUILD_NAME: "Jenkins PR Build"
                    currentBuild.rawBuild.@result = hudson.model.Result.ABORTED
                }
            }
        }
    }
}