// SPDX-FileCopyrightText: 2017 Fermi Research Alliance, LLC
// SPDX-License-Identifier: Apache-2.0

pipeline {
    agent { label 'podman' }
    stages{
        stage('DE tests') {
            parallel {
                stage('flake8') {
                    agent {
                        node {
                            label 'podman'
                            customWorkspace "${WORKSPACE}/${STAGE_NAME}"
                        }
                    }
                    options {
                        timeout(time: "${STAGE_TIMEOUT}", activity: false, unit: 'MINUTES')
                    }
                    steps {
                        script {
                            // DOCKER_IMAGE is defined through Jenkins project
                            flake8StageDockerImage="localhost/${DOCKER_IMAGE}_${BUILD_NUMBER}_${STAGE_NAME}"
                            // Set custom Build Name
                            if (params.GITHUB_PR_NUMBER) {
                                if (params.GITHUB_PR_STATE == 'CLOSED') {
                                    currentBuild.displayName="${BUILD_NUMBER}#${EL_VERSION}#PR#${GITHUB_PR_NUMBER}#CLOSED"
                                } else {
                                    currentBuild.displayName="${BUILD_NUMBER}#${EL_VERSION}#PR#${GITHUB_PR_NUMBER}"
                                }
                            } else {
                                currentBuild.displayName="${BUILD_NUMBER}#${BRANCH}"
                            }
                        }
                        echo "cleanup workspace"
                        sh 'for f in $(ls -A); do rm -rf ${f}; done'
                        // DE_REPO is defined through Jenkins project
                        echo "clone decisionengine code from ${DE_REPO}"
                        sh '''
                            git clone ${DE_REPO}
                            cd decisionengine
                            echo "checkout ${BRANCH} branch"
                            git checkout ${BRANCH}
                            echo GITHUB_PR_NUMBER: ${GITHUB_PR_NUMBER} - GITHUB_PR_STATE: ${GITHUB_PR_STATE}
                            if [[ -n ${GITHUB_PR_NUMBER} && ${GITHUB_PR_STATE} == OPEN ]]; then
                                git fetch origin pull/${GITHUB_PR_NUMBER}/merge:merge${GITHUB_PR_NUMBER}
                                git checkout merge${GITHUB_PR_NUMBER}
                            fi
                            cd ..
                        '''
                        echo "prepare podman image ${flake8StageDockerImage}"
                        sh "podman build --pull --tag ${flake8StageDockerImage} --build-arg BASEIMAGE=docker.io/hepcloud/decision-engine-ci-el9:${BRANCH} --build-arg UID=\$(id -u) --build-arg GID=\$(id -g) -f decisionengine/package/ci/EL9/Dockerfile decisionengine/package/ci/EL9/"
                        echo "Run ${STAGE_NAME} tests"
                        sh "podman run --userns keep-id:uid=\$(id -u),gid=\$(id -g) --rm --env PYTEST_TIMEOUT=${PYTEST_TIMEOUT} -v ${WORKSPACE}/decisionengine:${WORKSPACE}/decisionengine -w ${WORKSPACE}/decisionengine ${flake8StageDockerImage} \"-m flake8\" \"flake8.log\""
                    }
                    post {
                        always {
                            archiveArtifacts artifacts: "decisionengine/flake8.log"
                            // check if the podman container used for this test suite is still active, if so this is due to an aborted test suite
                            // eventually kill the python process that spawn the test to cleanup CI processes left behind
                            sh '''
                                PODMANID=$(podman ps | grep ${DOCKER_IMAGE}_${BUILD_NUMBER}_${STAGE_NAME} | awk '{print $1}')
                                if [[ -n ${PODMANID} ]]; then
                                    podman exec ${PODMANID} ps -xww && \
                                    KPID=$(podman exec ${PODMANID} ps -xww | grep python3 | head -1 | awk '{print $1}') && \
                                    podman exec ${PODMANID} kill -9 ${KPID} || true
                                    podman exec ${PODMANID} ps -xww  || true
                                fi
                            '''
                            echo "cleanup podman image ${flake8StageDockerImage}"
                            sh "podman rmi ${flake8StageDockerImage}"
                        }
                    }
                }
                stage('pylint') {
                    agent {
                        node {
                            label 'podman'
                            customWorkspace "${WORKSPACE}/${STAGE_NAME}"
                        }
                    }
                    options {
                        timeout(time: "${STAGE_TIMEOUT}", activity: false, unit: 'MINUTES')
                    }
                    steps {
                        script {
                            // DOCKER_IMAGE is defined through Jenkins project
                            pylintStageDockerImage="localhost/${DOCKER_IMAGE}_${BUILD_NUMBER}_${STAGE_NAME}"
                        }
                        echo "cleanup workspace"
                        sh 'for f in $(ls -A); do rm -rf ${f}; done'
                        // DE_REPO is defined through Jenkins project
                        echo "clone decisionengine code from ${DE_REPO}"
                        sh '''
                            git clone ${DE_REPO}
                            cd decisionengine
                            echo "checkout ${BRANCH} branch"
                            git checkout ${BRANCH}
                            echo GITHUB_PR_NUMBER: ${GITHUB_PR_NUMBER} - GITHUB_PR_STATE: ${GITHUB_PR_STATE}
                            if [[ -n ${GITHUB_PR_NUMBER} && ${GITHUB_PR_STATE} == OPEN ]]; then
                                git fetch origin pull/${GITHUB_PR_NUMBER}/merge:merge${GITHUB_PR_NUMBER}
                                git checkout merge${GITHUB_PR_NUMBER}
                            fi
                            cd ..
                        '''
                        echo "prepare podman image ${pylintStageDockerImage}"
                        sh "podman build --pull --tag ${pylintStageDockerImage} --build-arg BASEIMAGE=docker.io/hepcloud/decision-engine-ci-el9:${BRANCH} --build-arg UID=\$(id -u) --build-arg GID=\$(id -g) -f decisionengine/package/ci/EL9/Dockerfile decisionengine/package/ci/EL9/"
                        echo "Run ${STAGE_NAME} tests"
                        sh "podman run --userns keep-id:uid=\$(id -u),gid=\$(id -g) --rm --env PYTEST_TIMEOUT=${PYTEST_TIMEOUT} -v ${WORKSPACE}/decisionengine:${WORKSPACE}/decisionengine -w ${WORKSPACE}/decisionengine ${pylintStageDockerImage} \"-m pylint src/decisionengine/ src/tests/\" \"pylint.log\""
                    }
                    post {
                        always {
                            archiveArtifacts artifacts: "decisionengine/pylint.log"
                            // check if the podman container used for this test suite is still active, if so this is due to an aborted test suite
                            // eventually kill the python process that spawn the test to cleanup CI processes left behind
                            sh '''
                                PODMANID=$(podman ps | grep ${DOCKER_IMAGE}_${BUILD_NUMBER}_${STAGE_NAME} | awk '{print $1}')
                                if [[ -n ${PODMANID} ]]; then
                                    podman exec ${PODMANID} ps -xww && \
                                    KPID=$(podman exec ${PODMANID} ps -xww | grep python3 | head -1 | awk '{print $1}') && \
                                    podman exec ${PODMANID} kill -9 ${KPID} || true
                                    podman exec ${PODMANID} ps -xww  || true
                                fi
                            '''
                            echo "cleanup podman image ${pylintStageDockerImage}"
                            sh "podman rmi ${pylintStageDockerImage}"
                        }
                    }
                }
                stage('unit_tests') {
                    agent {
                        node {
                            label 'podman'
                            customWorkspace "${WORKSPACE}/${STAGE_NAME}"
                        }
                    }
                    options {
                        timeout(time: "${STAGE_TIMEOUT}", activity: false, unit: 'MINUTES')
                    }
                    steps {
                        script {
                            // DOCKER_IMAGE is defined through Jenkins project
                            unit_testsStageDockerImage="localhost/${DOCKER_IMAGE}_${BUILD_NUMBER}_${STAGE_NAME}"
                        }
                        echo "cleanup workspace"
                        sh 'for f in $(ls -A); do rm -rf ${f}; done'
                        // DE_REPO is defined through Jenkins project
                        echo "clone decisionengine code from ${DE_REPO}"
                        sh '''
                            git clone ${DE_REPO}
                            cd decisionengine
                            echo "checkout ${BRANCH} branch"
                            git checkout ${BRANCH}
                            echo GITHUB_PR_NUMBER: ${GITHUB_PR_NUMBER} - GITHUB_PR_STATE: ${GITHUB_PR_STATE}
                            if [[ -n ${GITHUB_PR_NUMBER} && ${GITHUB_PR_STATE} == OPEN ]]; then
                                git fetch origin pull/${GITHUB_PR_NUMBER}/merge:merge${GITHUB_PR_NUMBER}
                                git checkout merge${GITHUB_PR_NUMBER}
                            fi
                            cd ..
                        '''
                        echo "prepare podman image ${unit_testsStageDockerImage}"
                        sh "podman build --pull --tag ${unit_testsStageDockerImage} --build-arg BASEIMAGE=docker.io/hepcloud/decision-engine-ci-el9:${BRANCH} --build-arg UID=\$(id -u) --build-arg GID=\$(id -g) -f decisionengine/package/ci/EL9/Dockerfile decisionengine/package/ci/EL9/"
                        echo "Run ${STAGE_NAME} tests"
                        sh "podman run --userns keep-id:uid=\$(id -u),gid=\$(id -g) --rm --env PYTEST_TIMEOUT=${PYTEST_TIMEOUT} -v ${WORKSPACE}/decisionengine:${WORKSPACE}/decisionengine -w ${WORKSPACE}/decisionengine ${unit_testsStageDockerImage} \"-m pytest --cov-report term --cov=decisionengine --no-cov-on-fail\" \"pytest.log\""
                    }
                    post {
                        always {
                            archiveArtifacts artifacts: "decisionengine/pytest.log"
                            // check if the podman container used for this test suite is still active, if so this is due to an aborted test suite
                            // eventually kill the python process that spawn the test to cleanup CI processes left behind
                            sh '''
                                PODMANID=$(podman ps | grep ${DOCKER_IMAGE}_${BUILD_NUMBER}_${STAGE_NAME} | awk '{print $1}')
                                if [[ -n ${PODMANID} ]]; then
                                    podman exec ${PODMANID} ps -xww && \
                                    KPID=$(podman exec ${PODMANID} ps -xww | grep python3 | head -1 | awk '{print $1}') && \
                                    podman exec ${PODMANID} kill -9 ${KPID} || true
                                    podman exec ${PODMANID} ps -xww  || true
                                fi
                            '''
                            echo "cleanup podman image ${unit_testsStageDockerImage}"
                            sh "podman rmi ${unit_testsStageDockerImage}"
                        }
                    }
                }
                stage('DEbuild') {
                    agent {
                        node {
                            label 'podman'
                            customWorkspace "${WORKSPACE}/${STAGE_NAME}"
                        }
                    }
                    options {
                        timeout(time: "${STAGE_TIMEOUT}", activity: false, unit: 'MINUTES')
                    }
                    steps {
                        script {
                            // DOCKER_IMAGE is defined through Jenkins project
                            DEbuildStageDockerImage="localhost/${DOCKER_IMAGE}_${BUILD_NUMBER}_${STAGE_NAME}"
                        }
                        echo "cleanup workspace"
                        sh 'for f in $(ls -A); do rm -rf ${f}; done'
                        // DE_REPO is defined through Jenkins project
                        echo "clone decisionengine code from ${DE_REPO}"
                        sh '''
                            git clone ${DE_REPO}
                            cd decisionengine
                            echo "checkout ${BRANCH} branch"
                            git checkout ${BRANCH}
                            echo GITHUB_PR_NUMBER: ${GITHUB_PR_NUMBER} - GITHUB_PR_STATE: ${GITHUB_PR_STATE}
                            if [[ -n ${GITHUB_PR_NUMBER} && ${GITHUB_PR_STATE} == OPEN ]]; then
                                git fetch origin pull/${GITHUB_PR_NUMBER}/merge:merge${GITHUB_PR_NUMBER}
                                git checkout merge${GITHUB_PR_NUMBER}
                            fi
                            cd ..
                        '''
                        echo "clone decisionengine_modules code from ${DEM_REPO}"
                        sh '''
                            git clone ${DEM_REPO}
                            cd decisionengine_modules
                            echo "checkout ${BRANCH} branch"
                            git checkout ${BRANCH}
                            cd ..
                        '''
                        echo "prepare podman image ${DEbuildStageDockerImage}"
                        sh "podman build --pull --tag ${DEbuildStageDockerImage} --build-arg BASEIMAGE=docker.io/hepcloud/decision-engine-ci-el9:${BRANCH} --build-arg UID=\$(id -u) --build-arg GID=\$(id -g) -f decisionengine/package/ci/EL9/Dockerfile decisionengine/package/ci/EL9/"
                        echo "Run ${STAGE_NAME} tests"
                        sh "podman run --privileged --userns keep-id:uid=\$(id -u),gid=\$(id -g) --rm --env PYTEST_TIMEOUT=${PYTEST_TIMEOUT} -v ${WORKSPACE}:${WORKSPACE} -w ${WORKSPACE}/decisionengine ${DEbuildStageDockerImage} \"make-release\" \"make-release.log\""
                    }
                    post {
                        always {
                            archiveArtifacts artifacts: "dist/decisionengine*,rpmbuild/RPMS/decisionengine*"
                            // check if the podman container used for this test suite is still active, if so this is due to an aborted test suite
                            // eventually kill the python process that spawn the test to cleanup CI processes left behind
                            sh '''
                                PODMANID=$(podman ps | grep ${DOCKER_IMAGE}_${BUILD_NUMBER}_${STAGE_NAME} | awk '{print $1}')
                                if [[ -n ${PODMANID} ]]; then
                                    podman exec ${PODMANID} ps -xww && \
                                    KPID=$(podman exec ${PODMANID} ps -xww | grep python3 | head -1 | awk '{print $1}') && \
                                    podman exec ${PODMANID} kill -9 ${KPID} || true
                                    podman exec ${PODMANID} ps -xww  || true
                                fi
                            '''
                            echo "cleanup podman image ${DEbuildStageDockerImage}"
                            sh "podman rmi ${DEbuildStageDockerImage}"
                        }
                    }
                }
            }
        }
    }
}
