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

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

// Deploy jobs
RUNTIMES_DEPLOY = 'kogito-runtimes.weekly-deploy'
APPS_DEPLOY = 'kogito-apps.weekly-deploy'

// 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 = [:]

// Should be multibranch pipeline
pipeline {
    agent {
        label util.avoidFaultyNodes('ubuntu')
    }

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

    // parameters {
    // For parameters, check into ./dsl/jobs.groovy file
    // }

    environment {
        // Some generated env is also defined into ./dsl/jobs.groovy file
        KOGITO_CI_EMAIL_TO = credentials("${JENKINS_EMAIL_CREDS_ID}")

        CURRENT_DATE = getCurrentDate()

        WEEKLY_TAG = """${getBuildBranch()}-${CURRENT_DATE}"""
    }

    stages {
        stage('Initialize') {
            steps {
                script {
                    echo "weekly tag is ${env.WEEKLY_TAG}"

                    currentBuild.displayName = env.WEEKLY_TAG
                }
            }
        }

        stage('Build & Deploy Kogito Runtimes') {
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    addSkipTestsParam(buildParams)
                    addSkipIntegrationTestsParam(buildParams)
                    buildJob(RUNTIMES_DEPLOY, buildParams)
                }
            }
            post {
                failure {
                    addFailedStage(RUNTIMES_DEPLOY)
                }
            }
        }

        stage('Build & Deploy Kogito Apps') {
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    addSkipTestsParam(buildParams)
                    addSkipIntegrationTestsParam(buildParams)
                    buildJob(APPS_DEPLOY, buildParams)
                }
            }
            post {
                failure {
                    addFailedStage(APPS_DEPLOY)
                }
            }
        }

        stage('Start Cloud weekly') {
            when {
                expression { !params.SKIP_CLOUD_WEEKLY }
            }
            steps {
                script {
                    def buildParams = getDefaultBuildParams()
                    addSkipTestsParam(buildParams)
                    build(job: './0-kogito-weekly-cloud', wait: false, parameters: buildParams, propagate: false)
                }
            }
        }
    }
    post {
        unsuccessful {
            sendPipelineErrorNotification()
        }
    }
}

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

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

    // Set Unstable if job did not succeed
    if (!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("${env.STAGE_NAME}", jobKey)
}
void addUnstableStage(String jobKey = '') {
    UNSTABLE_STAGES.put("${env.STAGE_NAME}", jobKey)
}

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

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

List getDefaultBuildParams() {
    List params = []
    addStringParam(params, 'DISPLAY_NAME', env.WEEKLY_TAG)
    addStringParam(params, 'GIT_CHECKOUT_DATETIME', getCheckoutDatetime())
    addBooleanParam(params, 'SEND_NOTIFICATION', true)

    return params
}

void addSkipTestsParam(buildParams) {
    addBooleanParam(buildParams, 'SKIP_TESTS', params.SKIP_TESTS)
}

void addSkipIntegrationTestsParam(buildParams) {
    addBooleanParam(buildParams, 'SKIP_INTEGRATION_TESTS', params.SKIP_TESTS)
}

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 getCurrentDate() {
    return sh(returnStdout: true, script: 'date -u "+%Y-%m-%d"').trim()
}

String getCheckoutDatetime() {
    return env.CURRENT_DATE + ' 02:00' // Cut-off 02:00AM
}
