pipeline {
    agent { label "osx && arm64" }

    environment {
        BUILD_OPTIONS = ''
    }

    options {
        buildDiscarder(logRotator(numToKeepStr: '135', daysToKeepStr: '21'))
        gitLabConnection('GitLabConnectionJenkins')
        timestamps() // Add timestamps to all console output
    }

    stages {
        stage('clean previous runs and update gitlab commit status'){
            steps{
                deleteDir()
                updateGitlabCommitStatus(name: 'Build macos', 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{
                            env.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 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()
                            if (SDK_BRANCH == ""){
                                echo "SDK_BRANCH was not found on description so develop will be used by default"
                                env.SDK_BRANCH = "develop"
                            }
                            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('Checkout sources'){
            parallel{
                stage('Checkout MEGAcmd with prebuildmerge'){
                    steps{
                    checkout([
                        $class: 'GitSCM',
                        branches: [[name: "origin/${env.gitlabSourceBranch}"]],
                        userRemoteConfigs: [[ url: "${env.GIT_URL_MEGACMD}", 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}"]]
                                    ]
                    ])
                    }
                }
                stage('Checkout SDK'){
                    steps{
                    dir('sdk'){
                        checkout([
                        $class: 'GitSCM',
                        branches: [[name: "origin/${SDK_BRANCH}"]],
                        userRemoteConfigs: [[ url: "${env.GIT_URL_SDK}", credentialsId: "12492eb8-0278-4402-98f0-4412abfb65c1" ]],
                        extensions: [
                            [$class: "UserIdentity",name: "jenkins", email: "jenkins@jenkins"],
                            [$class: "CloneOption", depth: 1, shallow: true, noTags: false, reference: '']
                        ]
                        ])
                    }
                    script{
                        megacmd_sources_workspace = WORKSPACE
                        sdk_sources_workspace = "${megacmd_sources_workspace}/sdk"
                    }
                    }
                }
            }
        }
        stage('Build MEGAcmd'){
            environment{
                PATH = "cmdinstall/bin:${env.PATH}"
                BUILD_DIR = "cmdbuild"
                VCPKGPATH = "${env.HOME}/jenkins/vcpkg"
            }
            options{
                timeout(time: 3, unit: 'HOURS')
            }
            steps{
                sh "rm -rf ${BUILD_DIR}; mkdir ${BUILD_DIR}"
                sh "cmake -DCMAKE_VERBOSE_MAKEFILE=1 -DENABLE_MEGACMD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DVCPKG_ROOT=${VCPKGPATH} -DCMAKE_INSTALL_PREFIX=cmdinstall -S '${megacmd_sources_workspace}' -B ${BUILD_DIR} '${env.BUILD_OPTIONS}'"
                sh "cmake --build ${megacmd_sources_workspace}/${BUILD_DIR} -j 2"
                sh "cmake --install ${megacmd_sources_workspace}/${BUILD_DIR}"
            }
        }
        stage('Run unit tests') {
            environment {
                INSTALL_DIR = "${megacmd_sources_workspace}/cmdinstall"
                PATH = "${env.PATH}:${env.INSTALL_DIR}/mega-cmd-tests-unit.app/Contents/MacOS/"
                HOME = "${megacmd_sources_workspace}/unit-test-dir/home"
            }
            options {
                timeout(time: 15, unit: 'MINUTES')
            }
            steps {
                dir('unit-test-dir') {
                    echo "Running tests"
                    sh "mkdir -p \$HOME/Library/Caches"
                    sh "mega-cmd-tests-unit --gtest_output=xml:${megacmd_sources_workspace}/unit-test-dir/mega-cmd-tests.xml --gtest_shuffle"
                }
            }
            post {
                always {
                    archiveArtifacts artifacts: "unit-test-dir/home/.megaCmd/megacmdserver.log*", allowEmptyArchive: true
                    junit testResults: "unit-test-dir/mega-cmd-tests.xml", keepProperties: true
                }
            }
        }
        stage('Run integration tests') {
            options {
                timeout(time: 1, unit: 'HOURS')
            }
            environment {
                INSTALL_DIR = "${megacmd_sources_workspace}/cmdinstall"
                PATH = "${env.PATH}:${env.INSTALL_DIR}/bin:${env.INSTALL_DIR}/mega-cmd-tests-integration.app/Contents/MacOS/"
                HOME = "${megacmd_sources_workspace}/integration-test-dir/home"
                MEGACMD_TEST_USER = ''
                MEGACMD_TEST_PASS = credentials('MEGACMD_TESTS_PASSWORD')
                MEGACMD_SOCKET_NAME = "sock_${env.BUILD_ID}"
            }
            steps {
                lock(label: 'testing_accounts_megacmd', variable: 'MEGACMD_TEST_USER', quantity: 1, resource: null) {
                    dir('integration-test-dir') {
                        echo "Running tests"
                        sh "mkdir -p \$HOME/Library/Caches"
                        sh "mega-cmd-tests-integration --gtest_output=xml:${megacmd_sources_workspace}/integration-test-dir/mega-cmd-tests.xml --gtest_shuffle"
                    }
                }
            }
            post {
                always {
                    archiveArtifacts "integration-test-dir/home/.megaCmd/megacmdserver.log*"
                    junit testResults: "integration-test-dir/mega-cmd-tests.xml", keepProperties: true
                }
            }
        }
    }

    post {
        always {
            script {
                if (currentBuild.currentResult == 'SUCCESS') {
                    addGitLabMRComment(comment: ":white_check_mark: ${currentBuild.projectName} :green_apple: <b>macOS</b> SUCCEEDED :muscle:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build macos', state: 'success')
                }
                if (currentBuild.currentResult == 'FAILURE') {
                    addGitLabMRComment(comment: ":red_circle: ${currentBuild.projectName} :green_apple: <b>macOS</b> FAILURE  :worried:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build macos', state: 'failed')
                }
                if (currentBuild.currentResult == 'ABORTED') {
                    addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} :green_apple: <b>macOS</b> ABORTED  :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build macos', state: 'canceled')
                }
                if (currentBuild.currentResult == 'UNSTABLE') {
                    addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} :green_apple: <b>macOS</b> UNSTABLE  :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${env.GIT_COMMIT}" )
                    updateGitlabCommitStatus(name: 'Build macos', state: 'failed')
                }
            }
            deleteDir()
        }
    }
}
