pipeline {
    agent { label 'linux && amd64 && webrtc' }
    options { 
        buildDiscarder(logRotator(numToKeepStr: '135', daysToKeepStr: '21'))
        gitLabConnection('GitLabConnectionJenkins')
    }

    environment {
        BUILD_OPTIONS = ' '
        APIURL_TO_TEST = ' '
    }

    stages {
        stage('clean previous runs and update gitlab commit status'){
            steps{
                deleteDir()
                updateGitlabCommitStatus(name: 'Build & test MEGAchat', state: 'running')
            }
        }
        stage('Get build parameters'){
            parallel{
                stage('Get build options'){
                    when {
                        allOf {
                            expression { env.gitlabTriggerPhrase != null }
                            expression { env.gitlabTriggerPhrase.contains('BUILD_OPTIONS') }
                        }
                    }
                    steps {
                        script{
                            BUILD_OPTIONS = sh(script: 'echo "$gitlabTriggerPhrase" | grep BUILD_OPTIONS | awk -F "BUILD_OPTIONS="  \'{print \$2}\' | cut -d"\"" -f2', returnStdout: true).trim()
                            println BUILD_OPTIONS
                        }
                    }
                    post{
                        always {
                            script{                        
                                if (currentBuild.currentResult == 'FAILURE'){
                                    addGitLabMRComment(comment: ":red_circle: ${env.JOB_NAME} FAILURE when getting the additional build parameters :worried:<br/>Build results: [Jenkins [${env.JOB_NAME} ${env.BUILD_DISPLAY_NAME}]](${env.RUN_DISPLAY_URL})<br/>Commit: ${env.GIT_COMMIT}" )
                                }
                            }
                        }
                    }
                }

                stage('Get MEGAchat branch'){
                    steps {
                        script{
                            env.MEGACHAT_BRANCH = sh(script: 'echo "$gitlabMergeRequestDescription" | grep MEGACHAT_BRANCH_TO_TEST | awk -F "MEGACHAT_BRANCH_TO_TEST="  \'{print \$2}\' | cut -d" " -f1', returnStdout: true).trim()
                            if (MEGACHAT_BRANCH == ""){
                                echo "MEGACHAT_BRANCH was not found on description so develop will be used by default"
                                env.MEGACHAT_BRANCH = "develop"
                            }
                            println MEGACHAT_BRANCH
                        }
                    }
                    post{
                        always {
                            script{                        
                                if (currentBuild.currentResult == 'FAILURE'){
                                    addGitLabMRComment(comment: ":red_circle: ${env.JOB_NAME} FAILURE when getting the MEGAchat branch :worried:<br/>Build results: [Jenkins [${env.JOB_NAME} ${env.BUILD_DISPLAY_NAME}]](${env.RUN_DISPLAY_URL})<br/>Commit: ${env.GIT_COMMIT}" )
                                }
                            }
                        }
                    }
                }

                stage('Get API URL'){
                    steps {
                        script{
                            APIURL_TO_TEST = sh(script: 'echo "$gitlabMergeRequestDescription" | grep USE_APIURL_TO_TEST | awk -F "USE_APIURL_TO_TEST="  \'{print \$2}\' | cut -d" " -f1', returnStdout: true).trim()
                            println APIURL_TO_TEST
                            if (APIURL_TO_TEST == ""){
                                APIURL_TO_TEST = "https://g.api.mega.co.nz/"
                                echo "APIURL_TO_TEST was not found on description so ${APIURL_TO_TEST} will be used by default"
                            }
                            echo "APIURL_TO_TEST will be ${APIURL_TO_TEST}"
                        }
                    }
                    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('Checkout SDK and MEGAchat'){
            steps {
                //Clone MEGAchat
                sh "echo Cloning MEGAchat branch ${MEGACHAT_BRANCH}"
                checkout([
                    $class: 'GitSCM', 
                    branches: [[name: "origin/${MEGACHAT_BRANCH}"]],
                    userRemoteConfigs: [[ url: "${env.GIT_URL_MEGACHAT}", credentialsId: "12492eb8-0278-4402-98f0-4412abfb65c1" ]],
                    extensions: [
                        [$class: "UserIdentity",name: "jenkins", email: "jenkins@jenkins"]
                        ]
                ])
                dir('third-party/mega'){  
                    //Clone SDK (with PreBuildMerge)                      
                    checkout([
                        $class: 'GitSCM', 
                        branches: [[name: "origin/${env.gitlabSourceBranch}"]],
                        userRemoteConfigs: [[ url: "${env.GIT_URL_SDK}", 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{
                    megachat_sources_workspace = WORKSPACE
                    sdk_sources_workspace = "${megachat_sources_workspace}/third-party/mega"
                }
            }
        }

        stage('Build MEGAchat'){
            environment{
                WEBRTC_SRC="/home/jenkins/webrtc/src"
                PATH = "/home/jenkins/tools/depot_tools:${env.PATH}"
            }
            options{
                timeout(time: 150, unit: 'MINUTES')
            }
            steps{
                dir(megachat_sources_workspace){
                    sh "sed -i \"s#MEGAChatTest#${env.USER_AGENT_TESTS}#g\" tests/sdk_test/sdk_test.h"
                    sh "mkdir -p build"
                }
                dir(sdk_sources_workspace){
                    sh "./autogen.sh"
                    sh "./configure --disable-tests --enable-chat --enable-shared --without-pdfium --without-ffmpeg"
                    sh "sed -i \"s#nproc#echo 1#\" bindings/qt/build_with_webrtc.sh"
                    sh "cd bindings/qt && bash build_with_webrtc.sh all withExamples"
                }

            }
        }
        stage('Run MEGAchat tests'){
            environment {
                MEGA_PWD0 = credentials('MEGA_PWD_DEFAULT')
                MEGA_PWD1 = credentials('MEGA_PWD_DEFAULT')
                MEGA_PWD2 = credentials('MEGA_PWD_DEFAULT')
            }
            options{
                timeout(time: 300, unit: 'MINUTES')
            }
            steps{
                lock(label: 'SDK_Test_Accounts', variable: 'ACCOUNTS_COMBINATION', quantity: 1, resource: null){
                    dir("${megachat_sources_workspace}/build/subfolder"){
                        script{
                            def accounts_array = "${env.ACCOUNTS_COMBINATION}".split(',')
                            env.MEGA_EMAIL0 = accounts_array[0]
                            env.MEGA_EMAIL1 = accounts_array[1]
                            env.MEGA_EMAIL2 = accounts_array[2]
                            echo "${env.ACCOUNTS_COMBINATION}"
                        }
                        sh "ln -sfr ${megachat_sources_workspace}/build/MEGAchatTests/megachat_tests megachat_tests"
                        sh """
                        ulimit -c unlimited
                        ./megachat_tests ${APIURL_TO_TEST} || FAILED=1
                        if [ -n \"\$FAILED\" ]; then
                            maxTime=10
                            startTime=`date +%s`
                            while [ ! -e \"core\" -o -n \"\$( lsof core 2>/dev/null )\" ] && [ \$( expr `date +%s` - \$startTime ) -lt \$maxTime ]; do
                                echo "Waiting for core dump..."
                                sleep 1
                            done
                            if [ -e \"core\" ] && [ -z \"\$( lsof core 2>/dev/null )\" ]; then
                                echo "Processing core dump..."
                                echo thread apply all bt > backtrace
                                echo quit >> backtrace
                                gdb -q ./megachat_tests core -x ${megachat_sources_workspace}/build/subfolder/backtrace
                                tar chvzf core.tar.gz core megachat_tests
                            fi
                        fi
                        gzip -c test.log > test_${BUILD_ID}.log.gz || :
                        rm test.log || :
                        if [ ! -z \"\$FAILED\" ]; then
                            false
                        fi
                        """
                    }
                }
            }
        }
    }     
    post{
        always {
            archiveArtifacts artifacts: 'build/subfolder/test*.log*, build/subfolder/core.tar.gz', fingerprint: true
            script{
                if (currentBuild.currentResult == 'SUCCESS'){
                    addGitLabMRComment(comment: ":white_check_mark: ${currentBuild.projectName} :penguin: <b>MEGAchat</b> SUCCEEDED :muscle:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build & test MEGAchat', state: 'success')
                }                                
                if (currentBuild.currentResult == 'FAILURE'){
                    addGitLabMRComment(comment: ":red_circle: ${currentBuild.projectName} :penguin: <b>MEGAchat</b> FAILURE  :worried:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build & test MEGAchat', state: 'failed')
                }
                if (currentBuild.currentResult == 'ABORTED'){
                    addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} :penguin: <b>MEGAchat</b> ABORTED  :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build & test MEGAchat', state: 'canceled')
                }                                
                if (currentBuild.currentResult == 'UNSTABLE'){
                    addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} :penguin: <b>MEGAchat</b> UNSTABLE  :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build & test MEGAchat', state: 'failed')
                }
            }
        }
    }
}
