import org.jenkinsci.plugins.workflow.libs.Library

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

// Map of executed jobs
// See https://javadoc.jenkins.io/plugin/workflow-support/org/jenkinsci/plugins/workflow/support/steps/build/RunWrapper.html
// for more options on built job entity
JOBS = [:]

FAILED_STAGES = [:]
UNSTABLE_STAGES = [:]

pipeline {
    agent {
        label util.avoidFaultyNodes('ubuntu')
    }

    options {
        timeout(time: 360, unit: 'MINUTES')
    }

    environment {
        KOGITO_CI_EMAIL_TO = credentials("${JENKINS_EMAIL_CREDS_ID}")
    }

    stages {
        stage('Initialize') {
            steps {
                script {
                    currentBuild.displayName = getKogitoVersion()
                }
            }
        }

        stage('Init Kogito Runtimes') {
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    addDroolsVersionParam(buildParams)
                    addKogitoVersionParam(buildParams)
                    buildJob('kogito-runtimes', buildParams)
                }
            }
            post {
                failure {
                    addFailedStage('kogito-runtimes')
                }
            }
        }

        stage('Init Kogito Apps') {
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    addKogitoVersionParam(buildParams)
                    buildJob('kogito-apps', buildParams)
                }
            }
            post {
                failure {
                    addFailedStage('kogito-apps')
                }
            }
        }

        stage('Init Kogito Examples') {
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    addDroolsVersionParam(buildParams)
                    addKogitoVersionParam(buildParams)
                    buildJob('kogito-examples', buildParams)

                    if (isJobSucceeded('kogito-examples') || isJobUnstable('kogito-examples')) {
                        // Update examples nightly branch
                        dir('kogito-examples') {
                            deleteDir()
                            checkout(githubscm.resolveRepository('incubator-kie-kogito-examples', getGitAuthor(), getBuildBranch(), false, getGitAuthorCredsId()))
                            String nightlyBranch = "nightly-${getBuildBranch()}"
                            githubscm.createBranch(nightlyBranch)
                            githubscm.pushObject('origin', nightlyBranch, getGitAuthorPushCredsId())
                        }
                    }
                }
            }
            post {
                failure {
                    addFailedStage('kogito-examples')
                }
            }
        }

        stage('Init Docs') {
            when {
                expression { return isMainStream() }
            }
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    buildJob('kogito-docs', buildParams)
                }
            }
            post {
                failure {
                    addFailedStage('kogito-docs')
                }
            }
        }

        // Launch the nightly to deploy all artifacts from the branch
        stage('Launch the nightly') {
            when {
                expression { return params.DEPLOY }
            }
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    addBooleanParam(buildParams, 'SKIP_TESTS', true)
                    build(job: '../nightly/0-kogito-nightly', wait: false, parameters: buildParams, propagate: false)
                }
            }
        }

        // Launch the weekly to deploy all artifacts from the branch
        stage('Launch the weekly') {
            when {
                expression { return params.DEPLOY }
            }
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    addBooleanParam(buildParams, 'SKIP_TESTS', true)
                    build(job: '../other/0-kogito-weekly', wait: false, parameters: buildParams, propagate: false)
                }
            }
        }
    }
    post {
        unsuccessful {
            sendPipelineErrorNotification()
        }
    }
}

def buildJob(String jobName, List buildParams, String jobKey = jobName, boolean waitForJob = true) {
    echo "[${jobKey}] Build ${jobName} with params ${buildParams}"

    def job = build(job: "${jobName}", wait: waitForJob, parameters: buildParams, propagate: false)
    JOBS[jobKey] = job

    // Set Unstable if job did not succeed
    if (waitForJob && !isJobSucceeded(jobKey)) {
        addUnstableStage(jobKey)
        unstable("Job ${jobName} finished with result ${job.result}")
    }
    return job
}

def getJob(String jobKey) {
    return JOBS[jobKey]
}

String getJobUrl(String jobKey) {
    echo "getJobUrl for ${jobKey}"
    return getJob(jobKey)?.absoluteUrl ?: ''
}

boolean isJobSucceeded(String jobKey) {
    return getJob(jobKey)?.result == 'SUCCESS'
}

boolean isJobUnstable(String jobKey) {
    return getJob(jobKey)?.result == 'UNSTABLE'
}

void addFailedStage(String jobKey = '') {
    FAILED_STAGES.put("${STAGE_NAME}", jobKey)
}
void addUnstableStage(String jobKey = '') {
    UNSTABLE_STAGES.put("${STAGE_NAME}", jobKey)
}

void sendPipelineErrorNotification() {
    String bodyMsg = "Kogito setup branch job #${BUILD_NUMBER} was: ${currentBuild.currentResult}"

    if (FAILED_STAGES.size()) {
        bodyMsg += '\nFailed stages: \n- '
        bodyMsg += FAILED_STAGES.collect { "${it.key} => ${getJobUrl(it.value)}" }.join('\n- ')
    }
    bodyMsg += '\n'
    if (UNSTABLE_STAGES.size()) {
        bodyMsg += '\nUnstable stages: \n- '
        bodyMsg += UNSTABLE_STAGES.collect { "${it.key} => ${getJobUrl(it.value)}" }.join('\n- ')
    }
    bodyMsg += '\n'
    bodyMsg += "\nPlease look here: ${BUILD_URL}"
    emailext body: bodyMsg, subject: "[${getBuildBranch()}][d] Setup branch",
                to: env.KOGITO_CI_EMAIL_TO
}

List getDefaultBuildParams() {
    List buildParams = []
    addStringParam(buildParams, 'DISPLAY_NAME', getKogitoVersion())
    addBooleanParam(buildParams, 'SEND_NOTIFICATION', true)
    return buildParams
}

void addDroolsVersionParam(buildParams) {
    addStringParam(buildParams, 'DROOLS_VERSION', getDroolsVersion())
}

void addKogitoVersionParam(buildParams) {
    addStringParam(buildParams, 'KOGITO_VERSION', getKogitoVersion())
}

void addStringParam(List params, String key, String value) {
    params.add(string(name: key, value: value))
}

void addBooleanParam(List params, String key, boolean value) {
    params.add(booleanParam(name: key, value: value))
}

String getBuildBranch() {
    return env.GIT_BRANCH_NAME
}

String getGitAuthor() {
    return env.GIT_AUTHOR
}

String getGitAuthorCredsId() {
    return env.GIT_AUTHOR_CREDS_ID
}

String getGitAuthorPushCredsId() {
    return env.GIT_AUTHOR_PUSH_CREDS_ID
}

String getDroolsVersion() {
    return params.DROOLS_VERSION ?: getVersionFromReleaseBranch(getBuildBranch())
}

String getKogitoVersion() {
    return params.KOGITO_VERSION ?: getVersionFromReleaseBranch(getBuildBranch())
}

String getVersionFromReleaseBranch(String releaseBranch, int microVersion = 999, String suffix = 'SNAPSHOT') {
    String [] versionSplit = releaseBranch.split("\\.")
    if (versionSplit.length == 3
        && versionSplit[0].isNumber()
        && versionSplit[1].isNumber()
        && versionSplit[2] == 'x') {
        return "${versionSplit[0]}.${versionSplit[1]}.${microVersion}${suffix ? '-' + suffix : ''}"
    } else {
        error 'Cannot parse given branch as a release branch, aka [M].[m].x ...'
    }
}

boolean isMainStream() {
    return env.STREAM == 'main'
}
