pipeline {
    agent none
    options {
        buildDiscarder(logRotator(numToKeepStr: '135', daysToKeepStr: '21'))
        gitLabConnection('GitLabConnectionJenkins')
    }

    environment {
        BUILD_OPTIONS = ''
        TESTS_PARALLEL = ''
        APIURL_TO_TEST = ''
    }

    stages {
        stage('Update Gitlab commitStatus') {
            agent any
            steps {
                updateGitlabCommitStatus(name: 'Build & test windows', state: 'running')
                script{
                    COMMIT_ID = env.GIT_COMMIT
                    println GIT_COMMIT
                }
            }
        }
        stage('Build') {
            agent { label 'windows && amd64' }
            stages {
                stage('clean previous runs and update gitlab commit status'){
                    steps{
                        deleteDir()
                    }
                }
                stage('Get parameters'){
                    parallel{
                        stage('Get build and run paramters'){
                            steps {
                                script{
                                    BUILD_OPTIONS = sh(script: 'echo "$gitlabTriggerPhrase" | grep BUILD_OPTIONS | awk -F "BUILD_OPTIONS="  \'{print \$2}\' | cut -d"\\"" -f2 || :', returnStdout: true).trim()
                                    TESTS_PARALLEL = sh(script: 'echo "$gitlabTriggerPhrase" | grep "\\-\\-sequence" >/dev/null 2>&1 && echo "" || echo "--INSTANCES:10"', returnStdout: true).trim()
                                    GTEST_REPEAT = sh(script: 'echo "$gitlabTriggerPhrase" | grep --only-matching "\\-\\-gtest_repeat=[^ ]*" | awk -F "gtest_repeat="  \'{print "--gtest_repeat="\$2}\'|| :', returnStdout: true).trim()
                                    GTEST_FILTER = sh(script: 'echo "$gitlabTriggerPhrase" | grep --only-matching "\\-\\-gtest_filter=[^ ]*" | awk -F "gtest_filter="  \'{print "--gtest_filter="\$2}\'|| :', returnStdout: true).trim()
                                    println BUILD_OPTIONS
                                    println TESTS_PARALLEL
                                    println GTEST_REPEAT
                                    println GTEST_FILTER
                                }
                            }
                        }

                        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}"
                                }
                            }
                        }
                    }
                }
                stage('Checkout Windows'){
                    steps {
                        checkout([
                            $class: 'GitSCM',
                            branches: [[name: "${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{
                            windows_sources_workspace = WORKSPACE
                        }
                    }
                }
                stage('Build Windows'){
                    environment{
                        VCPKGPATH  = "${windows_sources_workspace}\\..\\vcpkg"
                        _MSPDBSRV_ENDPOINT_ = "${BUILD_TAG}"
                        TMP       = "${windows_sources_workspace}\\tmp"
                        TEMP      = "${windows_sources_workspace}\\tmp"
                        TMPDIR    = "${windows_sources_workspace}\\tmp"
                    }
                    options{
                        timeout(time: 150, unit: 'MINUTES')
                    }
                    steps{
                        dir(windows_sources_workspace){
                            //Build SDK
                            sh "echo Building SDK x64"
                            sh "mkdir build_dir"
                            sh "mkdir tmp"
                            sh "cmake -DENABLE_CHAT=ON -DVCPKG_ROOT='${VCPKGPATH}' ${BUILD_OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_GENERATOR_PLATFORM=x64 -S '${windows_sources_workspace}' -B '${windows_sources_workspace}'\\\\build_dir\\\\"
                            sh "cmake --build '${windows_sources_workspace}'\\\\build_dir\\\\ --config Debug -j 1"
                            sh "echo Building SDK x86"
                            sh "mkdir build_dir_x86"
                            sh "cmake -DENABLE_CHAT=ON -DVCPKG_ROOT='${VCPKGPATH}' ${BUILD_OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_GENERATOR_PLATFORM=Win32 -S '${windows_sources_workspace}' -B '${windows_sources_workspace}'\\\\build_dir_x86\\\\"
                            sh "cmake --build '${windows_sources_workspace}'\\\\build_dir_x86\\\\ --config Debug -j 1"
                        }
                    }
                }

                stage('Run Windows tests'){
                    options{
                        timeout(time: 250, unit: 'MINUTES')
                    }
                    environment {
                        PATH = "${windows_sources_workspace}\\\\vcpkg_installed\\\\x64-windows-mega\\\\debug\\\\bin;${env.PATH}"
                        MEGA_PWD = credentials('MEGA_PWD_DEFAULT')
                        MEGA_PWD_AUX = credentials('MEGA_PWD_DEFAULT')
                        MEGA_PWD_AUX2 = credentials('MEGA_PWD_DEFAULT')
                        MEGA_REAL_PWD=credentials('MEGA_REAL_PWD_TEST')
                    }
                    steps{
                        script {
                            def lockLabel = ''
                            if ("${APIURL_TO_TEST}" == 'https://g.api.mega.co.nz/') {
                                lockLabel = 'SDK_Concurrent_Test_Accounts'
                            } else  {
                                lockLabel = 'SDK_Concurrent_Test_Accounts_Staging'
                            }
                            lock(label: lockLabel, variable: 'ACCOUNTS_COMBINATION', quantity: 1, resourceSelectStrategy: "random", resource: null){
                                dir("${windows_sources_workspace}") {
                                    script{
                                        env.MEGA_EMAIL = "${env.ACCOUNTS_COMBINATION}"
                                        echo "${env.ACCOUNTS_COMBINATION}"
                                    }
                                    sh "echo Running tests"
                                    bat """

                                    cd build_dir

                                    tests\\\\unit\\\\Debug\\\\test_unit.exe
                                    if %ERRORLEVEL% NEQ 0 exit 1
                                    set gfxworkerTestIntegration=tools\\\\gfxworker\\\\tests\\\\integration\\\\Debug\\\\gfxworker_test_integration.exe
                                    if exist %gfxworkerTestIntegration% %gfxworkerTestIntegration%
                                    if %ERRORLEVEL% NEQ 0 exit 1
                                    tests\\\\integration\\\\Debug\\\\test_integration.exe --CI --USERAGENT:${env.USER_AGENT_TESTS_SDK} --APIURL:${APIURL_TO_TEST} ${GTEST_FILTER} ${GTEST_REPEAT} ${TESTS_PARALLEL}
                                    if %ERRORLEVEL% NEQ 0 set ERROR_VAL=1
                                    gzip -c test_integration.log > test_integration_${BUILD_ID}.log.gz
                                    rm test_integration.log
                                    exit %ERROR_VAL%
                                    """
                                }
                            }
                        }
                    }
                }
            }
            post{
                always {
                    archiveArtifacts artifacts: 'build_dir/test_integration*log*', fingerprint: true
                    deleteDir()
                }
            }
        }
    }
    post {
        success {
            updateGitlabCommitStatus(name: 'Build & test windows', state: 'success')
            addGitLabMRComment(comment: ":white_check_mark: ${currentBuild.projectName} <b>Windows</b> SUCCEEDED :muscle:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${COMMIT_ID}" )
        }
        unstable {
            updateGitlabCommitStatus(name: 'Build & test windows', state: 'failed')
            addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} <b>Windows</b> UNSTABLE  :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${COMMIT_ID}" )      
        }
        aborted {
            updateGitlabCommitStatus(name: 'Build & test windows', state: 'canceled')
            addGitLabMRComment(comment: ":interrobang: ${currentBuild.projectName} <b>Windows</b> ABORTED  :confused:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${COMMIT_ID}" )
        }
        failure {
            updateGitlabCommitStatus(name: 'Build & test windows', state: 'failed')
            addGitLabMRComment(comment: ":red_circle: ${currentBuild.projectName} <b>Windows</b> FAILURE  :worried:<br/>Build results: [Jenkins [${currentBuild.displayName}]](${currentBuild.absoluteUrl})<br/>Commit: ${COMMIT_ID}" )                
        }
    }
}
