string GITHUB_REPOSITORY = 'k6-hybrid-performance-tests'
string ECR_ACCOUNT_ID = '086679231553'
string QA_ACCOUNT_ID = '437795906767'
String SESSION_NAME = 'qa-k6-hybrid-performance-tests-job'
List<String> AWS_REGIONS = ['us-east-1']

pipeline {
    agent any

    options {
        ansiColor('xterm')
        disableConcurrentBuilds()
        timestamps()
    }

    parameters {
        string(
            name: 'SHARED_LIBRARIES_VERSION',
            defaultValue: 'master',
            description: 'The version of the Jenkins shared libraries to use. Can be a branch, tag or Git revision.'
        )
        booleanParam(
            name: 'RUN_TESTS',
            defaultValue: false,
            description: 'True to run tests, false to deploy Docker container.'
        )
        booleanParam(
            name: 'RUN_TESTS_ON_PR',
            defaultValue: false,
            description: 'True to run tests on a PR, false to run master container. Use to test a PR.'
        )
        string(
            name: 'TEST_FILE',
            defaultValue: '',
            description: 'Path to the test file from the tests directory.'
        )
        string(
            name: 'APP_URL',
            defaultValue: '',
            description: 'Url of the application to be tested'
        )
        string(
            name: 'BACKEND_SERVICE',
            defaultValue: '',
            description: 'Url of the microservice to be tested'
        )
        string(
            name: 'GRAPHQL_URL',
            defaultValue: 'https://qa-ows-grass.theorchard.io/graphql-gateway/graphql',
            description: 'GraphQL endpoint URL'
        )
        string(
            name: 'K6_BACKEND_STAGE_1_DURATION',
            defaultValue: '',
            description: 'Backend stage 1 duration, e.g "10s"'
        )
        string(
            name: 'K6_BACKEND_STAGE_1_VUS',
            defaultValue: '',
            description: 'Backend stage 1 VUs, e.g "1"'
        )
        string(
            name: 'K6_BACKEND_STAGE_2_DURATION',
            defaultValue: '',
            description: 'Backend stage 2 duration, e.g "10s"'
        )
        string(
            name: 'K6_BACKEND_STAGE_2_VUS',
            defaultValue: '',
            description: 'Backend stage 2 VUs, e.g "1"'
        )
        string(
            name: 'K6_BACKEND_START_VUS',
            defaultValue: '',
            description: 'Backend start VUs, e.g "1"'
        )
        string(
            name: 'K6_FRONTEND_VUS',
            defaultValue: '',
            description: 'Frontend VUs, e.g "1"'
        )
        string(
            name: 'K6_FRONTEND_START_TIME',
            defaultValue: '',
            description: 'Frontend start time, e.g "00s"'
        )
        string(
            name: 'K6_FRONTEND_DURATION',
            defaultValue: '',
            description: 'Frontend duration, e.g "20s"'
        )
        string(
            name: 'K6_GRACEFUL_STOP_DURATION',
            defaultValue: '',
            description: 'Length of time to ramp down load before stopping the test, e.g "180s"'
        )
        string(
            name: 'K6_METRIC_THRESHOLDS',
            defaultValue: '',
            description: 'Array of JSON objects with metric thresholds to apply to the test. See Readme for details.'
        )
    }

    stages {
        stage('Load Shared Libraries') {
            steps {
                library "jenkins-global-libraries@${params.SHARED_LIBRARIES_VERSION}"
            }
        }
        stage('Style Checks and Unit Tests') {
            when {
                expression { !params.RUN_TESTS }
            }
            steps {
                yarnRun scriptNames: ['lint', 'unit-test']
            }
        }
        stage('Deploy Docker Container') {
            when {
                expression {
                    (env.GIT_BRANCH == 'origin/master' || env.GIT_BRANCH == 'master') && !params.RUN_TESTS
                }
            }
            steps {
                dockerToEcr(
                    awsRegions: AWS_REGIONS,
                    ecrAccountId: ECR_ACCOUNT_ID,
                    imageName: 'k6-hybrid-performance-tests',
                    imageTag: env.GIT_COMMIT
                )
            }
        }
        stage('Run Tests Only') {
            when {
                expression { params.RUN_TESTS }
            }
            environment {
                BACKEND_SERVICE = "${params.BACKEND_SERVICE}"
                APP_URL = "${params.APP_URL}"
                GRAPHQL_URL = "${params.GRAPHQL_URL}"
                K6_BACKEND_STAGE_1_DURATION = "${params.K6_BACKEND_STAGE_1_DURATION}"
                K6_BACKEND_STAGE_1_VUS = "${params.K6_BACKEND_STAGE_1_VUS}"
                K6_BACKEND_STAGE_2_DURATION = "${params.K6_BACKEND_STAGE_2_DURATION}"
                K6_BACKEND_STAGE_2_VUS = "${params.K6_BACKEND_STAGE_2_VUS}"
                K6_BACKEND_START_VUS = "${params.K6_BACKEND_START_VUS}"
                K6_FRONTEND_VUS = "${params.K6_FRONTEND_VUS}"
                K6_FRONTEND_START_TIME = "${params.K6_FRONTEND_START_TIME}"
                K6_FRONTEND_DURATION = "${params.K6_FRONTEND_DURATION}"
                K6_GRACEFUL_STOP_DURATION = "${params.K6_GRACEFUL_STOP_DURATION}"
                K6_METRIC_THRESHOLDS = "${params.K6_METRIC_THRESHOLDS}"
            }
            steps {
                withEcr {
                    withAWS(role: 'qa-k6-hybrid-performance-tests-role', roleAccount: QA_ACCOUNT_ID,
                        roleSessionName: SESSION_NAME, useNode: true) {
                        withCredentials([string(credentialsId: 'github_packages_token', variable: 'GITHUB_TOKEN')]) {
                            sh """
                            if [ "${params.RUN_TESTS_ON_PR}" = "true" ]; then
                                make ci_run_PR_docker_k6_test TEST_FILE='${params.TEST_FILE.trim()}'
                            else
                                make ci_run_docker_k6_test TEST_FILE='${params.TEST_FILE.trim()}'
                            fi
                            """
                        }
                    }
                }
            }
            post {
                always {
                    archiveArtifacts artifacts: 'reports/html-report.html, reports/screenshots.zip, reports/summary.json, reports/summary.txt', allowEmptyArchive: true
                    script {
                        if (params.BACKEND_SERVICE) {
                            def slackFile = "${env.WORKSPACE}/reports/slackMessage.txt"
                            def slackSummary = readFile(file: slackFile)
                            def slackChannelFile = "${env.WORKSPACE}/reports/slackChannel.txt"
                            def slackChannel = readFile(file: slackChannelFile)
                            slackNotify channel: slackChannel, message: slackSummary
                        }
                    }
                }
            }
        }
    }
    post {
        always {
            cleanWs()
        }
    }
}
