// The below timeout is set in minutes
GLOBAL_TIMEOUT = 240
DOCKER_REGISTRY = "dcapdockerciregistry.azurecr.io"
GROOVY_FILE = "/.jenkins/src/Dcap.groovy"

// Tests running on hardware with custom path to libdcap_quoteprov.so
def ACCTest(String label, String version, String compiler, String build_type) {
    stage("${label} ${compiler} SGX1-FLC ${build_type}") {
        node("${label}") {
            timeout(GLOBAL_TIMEOUT) {
                cleanWs()
                checkout scm
                def dcap = load pwd() + GROOVY_FILE
                // Clone the Open Enclave repo
                dir("${WORKSPACE}/openenclave") {
                    git url: 'https://github.com/Microsoft/openenclave.git'
                }
                // Run hardware tests using the libdcap_quoteprov.so build
                def task = """
                    sudo apt install software-properties-common -y
                    sudo add-apt-repository ppa:team-xbmc/ppa -y
                    sudo apt-get update -y
                    sudo apt-get install nlohmann-json3-dev
                    cd ${WORKSPACE}/src/Linux
                    ./configure
                    make
                    mkdir -p ${WORKSPACE}/openenclave/build
                    cd ${WORKSPACE}/openenclave/build
                    git submodule update --recursive --init 
                    cmake ${WORKSPACE}/openenclave -G Ninja -DCMAKE_BUILD_TYPE=${build_type}
                    ninja -v
                    LD_LIBRARY_PATH=${WORKSPACE}/src/Linux ctest --output-on-failure
                    """
                dcap.Run(compiler, task)
            }
        }
    }
}

// Test using oetools-test Docker image with /dev/sgx_enclave and /dev/sgx_provision mounted inside container
def ACCContainerTest(String label, String version) {
    stage("Ubuntu ${version} Non-Simulation Container SGX1-FLC RelWithDebInfo") {
        node("${label}") {
            timeout(GLOBAL_TIMEOUT) {
                cleanWs()
                checkout scm
                def dcap = load pwd() + GROOVY_FILE
                // Clone the Open Enclave repo
                dir("${WORKSPACE}/openenclave") {
                    git url: 'https://github.com/Microsoft/openenclave.git'
                }
                // Run the OE tests from the git repository with the currently
                // generated az-dcap-client deb package installed
                def task = """
                        sudo apt-get update -y
                        sudo apt install software-properties-common -y
                        sudo add-apt-repository ppa:team-xbmc/ppa -y
                        sudo apt-get update -y
                        sudo apt-get install nlohmann-json3-dev
                        sudo apt-get install -y libgtest-dev
                        sudo apt-get install -y cmake
                        cd /usr/src/gtest
                        sudo cmake CMakeLists.txt
                        sudo make
                        find . -name "*.a" -exec sudo cp -t /usr/lib {} +
                        sudo apt-get purge az-dcap-client -y 
                        sudo apt-get update
                        sudo apt-get install sudo libcurl4-openssl-dev wget -y
                        cd ${WORKSPACE}/src/Linux
                        dpkg-buildpackage -us -uc
                        sudo dpkg -i ${WORKSPACE}/src/az-dcap-client_*_amd64.deb
                        mkdir -p ${WORKSPACE}/openenclave/build
                        sudo apt install ca-certificates
                        cd ${WORKSPACE}/openenclave/build
                        git submodule update --recursive --init
                        cmake ${WORKSPACE}/openenclave -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo
                        ninja -v
                        ctest --output-on-failure
                       """
                echo"***************************   ${version.trim()} ****************************"
                if(version.contains('20.04'))
                {
                    dcap.ContainerRun("${DOCKER_REGISTRY}/dcapdockerciregistry-ubuntu${version}:latest", "clang-10", task, "--cap-add=SYS_PTRACE --device /dev/sgx/enclave:/dev/sgx/enclave --device /dev/sgx/provision:/dev/sgx/provision --volume /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket")
                }
                else
                {
                    dcap.ContainerRun("${DOCKER_REGISTRY}/dcapdockerciregistry-ubuntu${version}:latest", "clang-10", task, "--cap-add=SYS_PTRACE --device /dev/sgx:/dev/sgx --volume /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket")
                } 			
            }
        }
    }
}

def ACCTestOeRelease(String label, String version) {
    stage("OpenEnclave release samples ${version}") {
        node("${label}") {
            timeout(GLOBAL_TIMEOUT) {
                cleanWs()
                checkout scm
                def dcap = load pwd() + GROOVY_FILE
                // Run the OE samples bundled with the published OE package, having
                // the currently generated az-dcap-client deb package installed
                def task = """
                        sudo apt-get update -y
                        sudo apt install software-properties-common -y
                        sudo add-apt-repository ppa:team-xbmc/ppa -y
                        sudo apt-get update -y
                        sudo apt-get install nlohmann-json3-dev
                        sudo apt-get install -y libgtest-dev
                        sudo apt-get install -y cmake
                        cd /usr/src/gtest
                        sudo cmake CMakeLists.txt
                        sudo make
                        find . -name "*.a" -exec sudo cp -t /usr/lib {} +
                        sudo apt-get purge az-dcap-client -y
                        sudo apt-get update
                        sudo apt-get install sudo libcurl4-openssl-dev wget -y
                        cd ${WORKSPACE}/src/Linux
                        dpkg-buildpackage -us -uc
                        sudo dpkg -i ${WORKSPACE}/src/az-dcap-client_*_amd64.deb
                        sudo apt-get update
                        sudo apt-get install -y open-enclave
                        /opt/openenclave/bin/oeapkman root
                        . /opt/openenclave/share/openenclave/openenclaverc
                        cp -r /opt/openenclave/share/openenclave/samples/ ~/samples
                        for DIR in \$(find ~/samples/* -maxdepth 0 -type d); do
                            cd \$DIR
                            make build
                            make run
                        done
                       """
                if(version.contains('20.04'))
                {
                    dcap.ContainerRun("${DOCKER_REGISTRY}/dcapdockerciregistry-ubuntu${version}:latest", "clang-10", task, "--cap-add=SYS_PTRACE --device /dev/sgx/enclave:/dev/sgx/enclave --device /dev/sgx/provision:/dev/sgx/provision --volume /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket")
                }
                else
                {
                    dcap.ContainerRun("${DOCKER_REGISTRY}/dcapdockerciregistry-ubuntu${version}:latest", "clang-10", task, "--cap-add=SYS_PTRACE --device /dev/sgx:/dev/sgx --volume /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket")
                }
			}
        }
    }
}

// Test DCAP build process
def DCAPBuildTest(String label, String build_type) {
    stage("${label} ${build_type}") {
        node("${label}") {
            timeout(GLOBAL_TIMEOUT) {
                cleanWs()
                checkout scm
                bat """
                    vcvars64.bat x64 && \
                    cd ${WORKSPACE}\\src\\Windows && \
                    nuget.exe restore dcap_provider.sln -PackagesDirectory packages && \
                    powershell -ExecutionPolicy Unrestricted -NoLogo -NonInteractive -Command ${WORKSPACE}\\src\\Windows\\get-prereqs.ps1 && \
                    cd ${WORKSPACE}\\src\\Windows\\dll && \
                    nuget.exe restore dcap_provider.vcxproj -PackagesDirectory packages && \
                    MSBuild.exe dcap_provider.vcxproj /p:Configuration=${build_type};Platform=x64 && \
                    cd ${WORKSPACE}\\src\\Windows\\UnitTests && \
                    nuget.exe restore UnitTests.vcxproj -PackagesDirectory packages && \
                    MSBuild.exe UnitTests.vcxproj /p:Configuration=${build_type};Platform=x64 && \
                    xcopy /y /c ${WORKSPACE}\\src\\Windows\\UnitTests\\x64\\${build_type}\\UnitTests.exe ${WORKSPACE}\\src\\Windows\\dll\\x64\\${build_type} && \
                    cd ${WORKSPACE}\\src\\Windows\\dll\\x64\\${build_type} && \
                    UnitTests.exe
                """
            }
        }
    }
}

parallel "ACC1804 SGX1-FLC Container RelWithDebInfo" : { ACCContainerTest('ACC-1804', '18.04') },
         "ACC1804 SGX1-FLC clang-10 Debug" :           { ACCTest('ACC-1804', '18.04', 'clang-10', 'Debug') },
         "ACC1804 SGX1-FLC clang-10 RelWithDebInfo" :  { ACCTest('ACC-1804', '18.04', 'clang-10', 'RelWithDebInfo') },
         "ACC1804 OpenEnclave Release Test" :          { ACCTestOeRelease('ACC-1804','18.04') },
         "ACC2004 SGX1-FLC Container RelWithDebInfo" : { ACCContainerTest('ACC-2004', '20.04') },
         "ACC2004 SGX1-FLC clang-10 Debug" :           { ACCTest('ACC-2004', '20.04', 'clang-10', 'Debug') },
         "ACC2004 SGX1-FLC clang-10 RelWithDebInfo" :  { ACCTest('ACC-2004', '20.04', 'clang-10', 'RelWithDebInfo') },
         "ACC2004 OpenEnclave Release Test" :          { ACCTestOeRelease('ACC-2004','20.04') },
         "ACCWin 2019 DCAP Debug Test" :               { DCAPBuildTest('SGXFLC-Windows-2019-DCAP', 'Debug') },
         "ACCWin 2019 DCAP Release Test" :             { DCAPBuildTest('SGXFLC-Windows-2019-DCAP', 'Release') }
