@Library('infraLib') _

def test_status = "missing"

pipeline {
    agent {
        label 'linux-agents-xlarge'
    }
    options {
        ansiColor('xterm')
        timestamps()
        buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '30')
    }
    //triggers {
    //  parameterizedCron('H 4 * * 1,3,5  %ENVIRONMENT=stage;GRADLE_TARGET=allSwaggerTests_JavaApi')
    //}
    environment {
        REPORTSDIR_SHORT = "allure-results"
        NOTIFICATIONS_CHANNEL = 'delphi-autotests-status'
        AWS_ASSUME_PROFILE = "gdb-delphi-prod"
//     JAVA_OPTS="-Xmx1024m -Xms256m -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap  -XX:MaxRAMFraction=1"
//     JAVA_OPTS="-Xmx4048m -Xms1024m -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap  -XX:MaxRAMFraction=1"
//     JAVA_OPTS="-Xmx4g -Xms2g -XX:+UnlockExperimentalVMOptions -XX:+UseContainerSupport -XX:+DoEscapeAnalysis -XX:+UseCompressedOops"
        JAVA_OPTS = "-Xmx8g -Xms4g -XX:+UseContainerSupport -XX:+UnlockExperimentalVMOptions -XX:+DoEscapeAnalysis -XX:+UseCompressedOops"
        /*
        AWS_ROLE_ARN = sh(script: "aws configure get ${env.AWS_ASSUME_PROFILE}.role_arn", returnStdout: true).trim()
        AWS_CREDS_JSON = sh(script: "aws sts assume-role --output json --role-arn ${env.AWS_ROLE_ARN} --duration-seconds 3600 --role-session-name session-${env.AWS_PROFILE}", returnStdout: true).trim()
        AWS_DEFAULT_REGION = sh(script: "aws configure get ${env.AWS_ASSUME_PROFILE}.region", returnStdout: true).trim()
        AWS_ACCESS_KEY_ID = sh(script: "set -euo pipefail; echo '${env.AWS_CREDS_JSON}' | jq -r .Credentials.AccessKeyId", returnStdout: true).trim()
        AWS_SECRET_ACCESS_KEY = sh(script: "set -euo pipefail; echo '${env.AWS_CREDS_JSON}' | jq -r .Credentials.SecretAccessKey", returnStdout: true).trim()
        AWS_SESSION_TOKEN = sh(script: "set -euo pipefail; echo '${env.AWS_CREDS_JSON}' | jq -r .Credentials.SessionToken", returnStdout: true).trim()
        */
        HOST = "delphi-api.delphiplatform.io"
        ENVIRONMENT = "${params.ENVIRONMENT}"
        PROXY = "no"
        ECR_REGISTRY_URL = '475275892927.dkr.ecr.us-east-1.amazonaws.com/delphi/qa-automation'
    }
    parameters {
        choice(
                choices: ['prod'],
                description: 'Set environment to test',
                name: 'ENVIRONMENT'
        )
        choice(
                choices: [
                        'api_smoke_prod_JavaApi'
                ],
                description: 'Set GRADLE_TARGET to run',
                name: 'GRADLE_TARGET'
        )
        booleanParam description: 'Check if you need to build a new docker image', name: 'BUILD_DOCKER_IMAGE'
    }
    stages {
        stage('Build test image') {
            when {
                expression { return params.BUILD_DOCKER_IMAGE }
            }
            steps {
                sh 'make docker/build'
                sh 'make docker/push'
            }
        }
        stage('Pull test image') {
            when {
                not { expression { return params.BUILD_DOCKER_IMAGE } }
            }
            steps {
                sh 'make docker/pull'
            }
        }
        stage('Docker stage') {
            agent {
                docker {
                    image "${env.ECR_REGISTRY_URL}:latest"
                    // The following args are aimed to workaround some issues with using Docker container as a Jenkins agent:
                    // 1. Disable image entrypoint to let Jenkins verify container was started correctly using custom commands.
                    // 2. Explicitly tell SBT locations for configs and local cache because Jenkins runs container using a
                    //    custom user (with `-u 1000:1000`) and SBT cannot resolve these paths automatically.
                    // 3. Set MaxMetaspaceSize to 1G due to OOM
                    args " --entrypoint '' -v ${env.HOME}/.aws:/home/gradle/.aws -v ${env.WORKSPACE}:/app --ulimit nofile=15000:16192"
                    reuseNode true
                }
            }
            stages {
                stage('Run the tests') {
                    environment {
                        REPORTSDIR = "/app/${env.REPORTSDIR_SHORT}"
                    }
                    steps {
                        sh '''
            unset AWS_ROLE_ARN
            unset AWS_CREDS_JSON
            unset AWS_DEFAULT_REGION
            unset AWS_ACCESS_KEY_ID
            unset AWS_SECRET_ACCESS_KEY
            unset AWS_SESSION_TOKEN
            set +x
            echo "=== Debug Limits ========"
            ulimit -a
            echo "========================="
            #export  AWS_ROLE_ARN="$(aws configure get ${AWS_ASSUME_PROFILE}.role_arn)"
            export  AWS_ROLE_ARN="arn:aws:iam::323555055331:role/cross_account_autotest_role"
            export  AWS_CREDS_JSON="$(aws sts assume-role --output json --role-arn ${AWS_ROLE_ARN} --duration-seconds 22000 --role-session-name session-${AWS_ASSUME_PROFILE})"
            export  AWS_DEFAULT_REGION="$(aws configure get ${AWS_ASSUME_PROFILE}.region)"
            export  AWS_ACCESS_KEY_ID="$(echo ${AWS_CREDS_JSON} | jq -r .Credentials.AccessKeyId)"
            export  AWS_SECRET_ACCESS_KEY="$(echo ${AWS_CREDS_JSON} | jq -r .Credentials.SecretAccessKey)"
            export  AWS_SESSION_TOKEN="$(echo ${AWS_CREDS_JSON} | jq -r .Credentials.SessionToken)"
            aws sts get-caller-identity
            set -x
            ./gradlew clean ${GRADLE_TARGET} -P"delphi.env.run=${ENVIRONMENT}" -P"delphi.api.host=${HOST}" --debug| tee runtime.log
            set +x
            if [ -d * ./build/allure-result/ ];
                then
                    echo "====== DEBUG: allure results exists"
                    ./gradlew _0copyAllureCategories
                else
                    echo "====== DEBUG: allure results NOT exists"
            fi
            '''
                        script {
                            test_status = sh(script: "cat runtime.log", returnStdout: true).trim()
                        }
                        sh '''
              if echo ${GRADLE_TARGET} | grep "JavaApi" > /dev/null ; then
                yes | cp -rf $WORKSPACE/src/test/resources/categories.json $WORKSPACE/build/allure-results/
                ./openapi/1_download_java_api_latest_as_openapi_3_yaml.sh &&
                ./openapi/2_download_swagger_coverage_commandline_tool_latest.sh &&
                ./openapi/3_convert_openapi_3_yaml_2_openapi_2_json.sh &&
                ./openapi/4_generate_java_api_coverage_from_swagger_2.sh
              else
                echo "INFO: GRADLE_TARGET=${GRADLE_TARGET} is not related to JavaApi, skipping report pre-processing..."
              fi
            '''
                    }
                }
            }
        }
    }
    post {
        always {
            sh "sudo chown -R ec2-user:ec2-user ${env.WORKSPACE}"
            script {
                allure([
                        includeProperties: false,
                        jdk              : '',
                        properties       : [],
                        reportBuildPolicy: 'ALWAYS',
                        results          : [[path: "build/allure-results"]]
                ])
            }
        }
        success {
            slackSend(
                    channel: "${env.NOTIFICATIONS_CHANNEL}",
                    iconEmoji: ':rocket:',
                    color: "good",
                    message: "Environment: ${params.ENVIRONMENT} <${env.BUILD_URL}/allure/|${env.JOB_NAME}>\n${test_status}"
            )
        }
        unsuccessful {
            slackSend(
                    channel: "${env.NOTIFICATIONS_CHANNEL}",
                    iconEmoji: ':flying_saucer:',
                    color: "danger",
                    message: "Environment: ${params.ENVIRONMENT} <${env.BUILD_URL}/allure/|${env.JOB_NAME}>\n${test_status}"
            )
        }
    }
}
