pipeline {
    agent { label 'linux && amd64' }

    options { 
        buildDiscarder(logRotator(numToKeepStr: '30', daysToKeepStr: '15'))
        gitLabConnection('GitLabConnectionJenkins')
    }

    stages {
        stage('clean previous runs and update gitlab commit status'){
            steps{
                deleteDir()
                updateGitlabCommitStatus(name: 'Build linux', state: 'running')
            }
        }
        stage('Get parameters'){
            parallel{
                stage('Get build options'){
                    steps {
                        script{
                            BUILD_OPTIONS = ' '
                            env.ARCHITECTURE = sh(script: 'echo "$gitlabTriggerPhrase" | grep ARCHITECTURE | awk -F "ARCHITECTURE="  \'{print \$2}\' | cut -d\\" -f2', returnStdout: true).trim()
                            if (env.ARCHITECTURE == "")
                                { env.ARCHITECTURE = "amd64" }
                            env.BUILD_OPTIONS = sh(script: 'echo "$gitlabTriggerPhrase" | grep BUILD_OPTIONS | awk -F "BUILD_OPTIONS="  \'{print \$2}\' | cut -d"\\"" -f2 || :', returnStdout: true).trim()
                            env.DISTRIBUTION = sh(script: 'echo "$gitlabTriggerPhrase" | grep DISTRIBUTION | awk -F "DISTRIBUTION="  \'{print \$2}\' | cut -d\\" -f2', returnStdout: true).trim()
                            if (env.DISTRIBUTION == "")
                                { env.DISTRIBUTION = "xUbuntu_24.04" }
                            println BUILD_OPTIONS
                            println DISTRIBUTION
                            println ARCHITECTURE
                        }
                    }
                }
                stage('Get SDK branch'){
                    steps {
                        script{
                            env.SDK_BRANCH = sh(script: 'echo "$gitlabMergeRequestDescription" | grep SDK_SUBMODULE_TEST | awk -F "SDK_SUBMODULE_TEST="  \'{print \$2}\' | cut -d" " -f1', returnStdout: true).trim()
                            println SDK_BRANCH
                        }
                    }
                    post{
                        always {
                            script{                        
                                if (currentBuild.currentResult == 'FAILURE'){
                                    addGitLabMRComment(comment: ":red_circle: ${env.JOB_NAME} FAILURE when getting the SDK branch :worried:<br/>Build results: [Jenkins [${env.JOB_NAME} ${env.BUILD_DISPLAY_NAME}]](${env.RUN_DISPLAY_URL})<br/>Commit: ${env.GIT_COMMIT}" )
                                }
                            }
                        }
                    }
                }

                stage('get MEGAsync team'){
                    when {
                        expression { 
                            env.gitlabMergeRequestDescription.contains('MEGASYNC_TEAM')
                        }
                    }
                    steps {
                        script{
                            println "${env.gitlabMergeRequestDescription}"
                            env.MEGASYNC_TEAM = sh(script: 'echo "$gitlabMergeRequestDescription" | grep MEGASYNC_TEAM | awk -F "MEGASYNC_TEAM="  \'{print \$2}\' | cut -d" " -f1', returnStdout: true).trim()
                            println MEGASYNC_TEAM
                        }
                    }
                }

            }
        }

        stage('Checkout and Compile Linux'){
            when {
                beforeAgent true
                anyOf {
                    expression { env.gitlabTriggerPhrase != null && env.gitlabTriggerPhrase.startsWith('trigger compilation')  }
                    allOf{
                        expression { env.gitlabTriggerPhrase == null }
                        triggeredBy "GitlabWebhookCause" 
                    }
                }
            }
            options{
                timeout(time: 120, unit: 'MINUTES')
            }
			environment{
				VCPKGPATH = "/opt/vcpkg"
				BUILD_DIR = "build_dir"
			}
            steps {
                checkout([
                    $class: 'GitSCM', 
                    branches: [[name: "origin/${env.gitlabSourceBranch}"]],
                    userRemoteConfigs: [[ url: "${env.GIT_URL_DESKTOP}", credentialsId: "12492eb8-0278-4402-98f0-4412abfb65c1" ]],
                    extensions: [
                        [$class: "UserIdentity",name: "jenkins", email: "jenkins@jenkins"],
                        [$class: 'PreBuildMerge', options: [fastForwardMode: 'FF', mergeRemote: "origin", mergeStrategy: 'DEFAULT', mergeTarget: "${env.gitlabTargetBranch}"]]
                        ]
                ])
                script { 
                    linux_sources_workspace = WORKSPACE
                }
                dir('src/MEGASync/mega'){
                    sh "echo Cloning SDK branch \"${SDK_BRANCH}\""
                    checkout([
                        $class: 'GitSCM',
                        branches: [[name: "${SDK_BRANCH}"]],
                        userRemoteConfigs: [[ url: "${env.GIT_URL_SDK}", credentialsId: "12492eb8-0278-4402-98f0-4412abfb65c1" ]],
                        extensions: [
                            [$class: "UserIdentity",name: "jenkins", email: "jenkins@jenkins"]
                        ]
                    ])
                }
                dir("${linux_sources_workspace}") {
					sh "rm -rf ${BUILD_DIR}; mkdir ${BUILD_DIR}"
                    sh "cmake -DCMAKE_BUILD_TYPE=Debug -DVCPKG_ROOT=${VCPKGPATH} ${BUILD_OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=ON -S ${linux_sources_workspace} -B ${linux_sources_workspace}/${BUILD_DIR}"
					sh "cmake --build ${linux_sources_workspace}/${BUILD_DIR} --target MEGAsync -j4"
                }
                script {
                    uploadPackagesExecuted = false
                }          
            }
        }


        stage('Checkout and build packages'){
            when {
                beforeAgent true
                expression { env.gitlabTriggerPhrase != null && (env.gitlabTriggerPhrase == 'trigger package' || env.gitlabTriggerPhrase.startsWith('trigger package linux'))  }
            }
            agent { label 'docker && ci-debian-11-64-2' }
            stages{
                stage('Checkout linux'){
                    steps {
                        checkout([
                            $class: 'GitSCM', 
                            branches: [[name: "origin/${env.gitlabSourceBranch}"]],
                            userRemoteConfigs: [[ url: "${env.GIT_URL_DESKTOP}", credentialsId: "12492eb8-0278-4402-98f0-4412abfb65c1" ]],
                            extensions: [
                                [$class: "UserIdentity",name: "jenkins", email: "jenkins@jenkins"],
                                ]
                        ])
                        script{
                            linux_sources_workspace = WORKSPACE
                        }
                        dir('src/MEGASync/mega'){
                            sh "echo Cloning SDK branch \"${SDK_BRANCH}\""
                            checkout([
                                $class: 'GitSCM',
                                branches: [[name: "${SDK_BRANCH}"]],
                                userRemoteConfigs: [[ url: "${env.GIT_URL_SDK}", credentialsId: "12492eb8-0278-4402-98f0-4412abfb65c1" ]],
                                extensions: [
                                    [$class: "UserIdentity",name: "jenkins", email: "jenkins@jenkins"]
                                ]
                            ])
                        }
                    }
                }
                stage('Build linux package'){
                    options {
                        //Extended timeout because arm64 packages can be built now.
                        timeout(time: 840, unit: 'MINUTES')
                    }
                    steps {
                        echo "Do Build for $DISTRIBUTION-$ARCHITECTURE"
                        dir(linux_sources_workspace){
                            lock(resource: "$DISTRIBUTION-$ARCHITECTURE-MEGAsync-build", quantity: 1, ){
                                sh "/opt/buildTools/build/buildManager.sh -a $ARCHITECTURE -j 5 build $DISTRIBUTION . megasync"
                                sh "/opt/buildTools/repo/repoManager.sh add /srv/builder/results/$DISTRIBUTION/$ARCHITECTURE/megasync/ $DISTRIBUTION"
                                sh "SIGN_KEY_PATH=/srv/sign_test/ /opt/buildTools/repo/repoManager.sh build -n $DISTRIBUTION"
                            }
                        }
                    }
                }
                stage ('Upload Linux package') {
                    steps {
                        dir(linux_sources_workspace){
                            script{
                                def ARCH_REGEX
                                switch (ARCHITECTURE) {
                                    case 'amd64':
                                        ARCH_REGEX = 'x86_64|amd64'
                                        break
                                    case 'arm64':
                                        ARCH_REGEX = 'aarch64|arm64'
                                        break
                                    default:
                                        ARCH_REGEX = ARCHITECTURE
                                }
                                withCredentials([string(credentialsId: 'MEGASYNC_ARTIFACTORY_TOKEN', variable: 'MEGASYNC_ARTIFACTORY_TOKEN')]) {
                                    sh """
                                        jf rt del \
                                            --url ${REPO_URL} \
                                            --access-token ${MEGASYNC_ARTIFACTORY_TOKEN} \
                                            MEGAsync-sprints/$MEGASYNC_TEAM/${env.gitlabMergeRequestIid}/linux/$DISTRIBUTION
                                    """
                                    dir("/srv/repo/private/$DISTRIBUTION"){
                                        sh """
                                            jf rt upload \
                                                --url ${REPO_URL} \
                                                --access-token ${MEGASYNC_ARTIFACTORY_TOKEN} \
                                                --regexp '(($ARCH_REGEX)/megasync.*deb\$|($ARCH_REGEX)/megasync.*rpm\$|($ARCH_REGEX)/megasync.*\\.pkg\\.tar\\.zst\$|($ARCH_REGEX)/megasync.*\\.pkg\\.tar\\.xz\$)' \
                                                MEGAsync-sprints/$MEGASYNC_TEAM/${env.gitlabMergeRequestIid}/linux/$DISTRIBUTION/
                                        """
                                    }
                                }
                                uploadPackagesExecuted = true
                            }
                        }
                    }
                }
            }
        }
    }
    post{
        always {
            deleteDir()
        }
        success {
            script{
                if (uploadPackagesExecuted){
                    addGitLabMRComment(comment: ":white_check_mark: ${currentBuild.projectName} :penguin: <b>LINUX</b>  SUCCEEDED :muscle:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}<br/>Packages URL: [${env.REPO_URL}/MEGAsync-sprints/$MEGASYNC_TEAM/${env.gitlabMergeRequestIid}/linux/$DISTRIBUTION]" )
                    updateGitlabCommitStatus(name: 'Build linux', state: 'success')
                } else {
                    addGitLabMRComment(comment: ":white_check_mark: ${currentBuild.projectName} :penguin: <b>Linux</b> SUCCEEDED :muscle:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build linux', state: 'success')
                }
            }
        }
        failure {
            addGitLabMRComment(comment: ":red_circle: ${currentBuild.projectName} :penguin: <b>Linux</b> FAILURE  :worried:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
            updateGitlabCommitStatus(name: 'Build linux', state: 'failed')
        }
        aborted {
            addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} :penguin: <b>Linux</b> ABORTED  :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
            updateGitlabCommitStatus(name: 'Build linux', state: 'canceled')
        }
    }
}
