/*********************************************************************
 *
 *  Jenkinsfile - cortex.langchain Build infrastructure
 *
 *********************************************************************/

// setCurrentBuildName - Increments the build number by one and sets it.
// Requires:
//     Plugin: https://plugins.jenkins.io/build-name-setter/
//     Allow sprintf permission
def setCurrentBuildName() {
    def lastSuccessfulBuild = currentBuild.previousSuccessfulBuild
    def lastBuildNumber = lastSuccessfulBuild ? lastSuccessfulBuild.displayName : "000.000"
    def (value1, value2) = lastBuildNumber.tokenize('.')
    while (value1.length() > 1 && value1[0] == "0") {
        value1 = value1[1 ..< value1.length()]
    }
    int value = value1.toInteger()
    value++
    while ((value % 10) > 7) { // Skip non-octal values
        value++
    }
    currentBuild.displayName = sprintf("%03d.000", value)
    env.bfmajor = sprintf("%03d", value)
    env.bfminor = "000"
}

def makeEmailBody() {
    def repo_name = "cortex.langchain"
    def body = []
    body << '<table border="1" cellpadding="1" cellspacing="0">'
    body << "<tr><td><b>Build</b></td><td>${currentBuild.fullDisplayName}</td></tr>"
    body << "<tr><td><b>Build Logs</b></td><td>${BUILD_URL}</td></tr>"
    // Collect builds since last good build
    def blds = []
    def bld = currentBuild
    while (true) {
        blds << bld
        bld = bld.previousBuild
        if (bld == null || bld.result == "SUCCESS") {
            break
        }
    }
    // Collect changes (commits)
    def allChanges = []
    for (b in blds.reverse()) {
        for (changeSet in b.changeSets) {
            for (change in changeSet) {
                allChanges << change
            }
        }
    }
    if (allChanges.size() > 0) {
        body << '<tr><td colSpan="2"><b>Change List</b></td></tr>'
        body << '<tr><td colSpan="2"><table border="1" cellpadding="1" cellspacing="0" width="100%">'
        for (change in allChanges) {
            body << "<tr><td><a href=\"https://alm.actian.com/bitbucket/projects/CRTX/repos/${repo_name}/commits/${change.commitId}\">${change.commitId[0..7]}</a></td>"
            body << "<td>${change.author.fullName}</td>"
            def msg = change.msg.replaceAll('VDE-[0-9]+', { "<a href=\"https://actian.atlassian.net/browse/${it}\">${it}</a>" })
            body << "<td>${msg}</td></tr>"
        }
        body << '</table></td></tr>'
    } else {
        body << '<tr><td colSpan="2">Change list is empty for this build.</td></tr>'
    }
    body << '</table>'
    return body.join('\n')
}

pipeline {
    agent none
    options {
        disableConcurrentBuilds()
        skipDefaultCheckout()
    }
    environment {
        PROJECT_NAME = 'cortex.langchain'
        bfmajor = '000' // hardcoded version 1.0.0; BUILD_DISPLAY_NAME is still used for publishing
        bfminor = '000'
        // builtins: BRANCH_NAME, BUILD_DISPLAY_NAME, BUILD_URL
    }
    stages {
        stage('Branch Check') {
            steps {
                script {
                    if (env.BRANCH_NAME != 'main') {
                        env.JF_DEV_BRANCH = "1"
                        if (   !(env.BRANCH_NAME =~ 'devbld$')
                            && !emailextrecipients([[$class: 'RequesterRecipientProvider']])) {
                            env.JF_SKIP_BUILD = "1"
                            error("Forcing an error to skip dev branch ${BRANCH_NAME}")
                        }
                    }
                }
            }
        }
        stage('Prepare Build') {
            steps {
                setCurrentBuildName()
            }
        }
        stage('Build') {
            agent { label 'gve-zenbuild05' }
            steps {
                cleanWs()
                checkout scm
                script {
                    if (env.JF_DEV_BRANCH) {
                        def commitEmail = sh(returnStdout: true, script: 'git log -1 --format=%ce')
                        env.JF_BUILD_EMAIL = commitEmail.trim()
                    }
                }
                sh "python3 cmbuild.py --tag ${BUILD_DISPLAY_NAME}"
                stash name: 'langchain-artifacts', includes: 'dist/**'
            }
            post {
                always {
                    archiveArtifacts artifacts: 'dist/**', allowEmptyArchive: true
                }
            }
        }
        stage('Publish') {
            when { branch "main" }
            agent { label 'gve-zenbuild05' }
            steps {
                unstash 'langchain-artifacts'
                sh "mkdir -p /mnt/fileserver/${PROJECT_NAME}/${BUILD_DISPLAY_NAME}"
                sh "rsync -a dist/ /mnt/fileserver/${PROJECT_NAME}/${BUILD_DISPLAY_NAME}/"
            }
        }
        stage('Git Push') {
            when { branch "main" }
            agent { label 'gve-zenbuild05' }
            environment {
                GIT_AUTH = credentials('b232b5ee-b37c-4eed-b5dd-423cf523e528')
                GIT_TAG  = "$BRANCH_NAME.$BUILD_DISPLAY_NAME"
            }
            steps {
                sh "git tag -a $GIT_TAG -m \"[Jenkins] Tag for $PROJECT_NAME.$BUILD_DISPLAY_NAME\""
                sh('''
                git config --local credential.helper "!f() { echo username=\\$GIT_AUTH_USR; echo password=\\$GIT_AUTH_PSW; }; f"
                git push origin $GIT_TAG
                ''')
            }
        }
    }
    post {
        failure {
            script {
                if (env.JF_DEV_BRANCH) {
                    if (!env.JF_SKIP_BUILD && env.JF_BUILD_EMAIL) {
                        emailext(body: '${DEFAULT_CONTENT}', mimeType: 'text/html',
                                 replyTo: 'jenkins@actian.com',
                                 subject: 'Jenkins: ${PROJECT_NAME} Build Failed (${BUILD_DISPLAY_NAME}) JENKINS_DEV_BUILD',
                                 to: env.JF_BUILD_EMAIL)
                    }
                } else {
                    emailext(body: '${DEFAULT_CONTENT}', mimeType: 'text/html',
                             replyTo: 'jenkins@actian.com',
                             subject: 'CM: ${PROJECT_NAME} Build Failed (${BUILD_DISPLAY_NAME})',
                             to: 'Build_Notice_PSQL@actian.com')
                }
            }
        }
        success {
            script {
                if (env.JF_DEV_BRANCH) {
                    if (env.JF_BUILD_EMAIL) {
                        emailext(body: '${DEFAULT_CONTENT}', mimeType: 'text/html',
                                 replyTo: 'jenkins@actian.com',
                                 subject: 'Jenkins: ${PROJECT_NAME} Build Complete (${BUILD_DISPLAY_NAME}) JENKINS_DEV_BUILD',
                                 to: env.JF_BUILD_EMAIL)
                    }
                } else {
                    emailext(body: makeEmailBody(), mimeType: 'text/html',
                             replyTo: 'jenkins@actian.com',
                             subject: 'CM: ${PROJECT_NAME} (${BUILD_DISPLAY_NAME}) Build Complete',
                             to: 'Build_Notice_PSQL@actian.com')
                }
            }
        }
    }
}