#!groovy
@Library('infraLib') _

def getAuthHostByEnv(String env_name) {
  switch (env_name) {
    case 'dev':
      return 'https://dev-um.atlas.stream/oauth/token'
    case 'qa':
      return 'https://qa-um.atlas.stream/oauth/token'
    case 'uat':
      return 'https://uat-um.atlas.stream/oauth/token'
    case 'prod':
      return 'https://um.atlas.stream/oauth/token'
  }
}

def getAuthProxyByEnv(String env_name) {
  switch (env_name) {
    case 'dev':
      return 'https://dev-auth.dna.stream'
    case 'qa':
      return 'https://qa-auth.dna.stream'
    case 'uat':
      return 'https://uat-auth.dna.stream'
    case 'prod':
      return 'https://auth.dna.stream'
  }
}

def getEnvBaseUrlByEnv(String env_name) {
  switch (env_name) {
    case 'dev':
      return 'https://dev.dna.stream'
    case 'qa':
      return 'https://qa.dna.stream'
    case 'uat':
      return 'https://uat.dna.stream'
    case 'prod':
      return 'https://alpha.dna.stream'
  }
}

def getTargetApiUrlByEnv(String env_name) {
  switch (env_name) {
    case 'dev':
      return 'https://dev-proxy.dna.stream'
    case 'qa':
      return 'https://qa-proxy.dna.stream'
    case 'uat':
      return 'https://uat-proxy.dna.stream'
    case 'prod':
      return 'https://proxy.dna.stream'
  }
}

def getNoMfaByEnv(String env_name) {
  switch (env_name) {
    case 'dev':
    case 'qa':
      return 'True'
    case 'uat':
    case 'prod':
      return 'False'
  }
}

def getClientId(String env_name) {
  switch (env_name) {
    case 'dev':
      return 'd6f07903-8fe5-4069-8e36-3a687f4c10b1'
    case 'qa':
      return '5d818d7c-d28b-4772-bf13-719e9a342a38'
    case 'uat':
      return 'TBD'
    case 'prod':
      return 'TBD'
  }
}

def testSummary

pipeline {

  agent {
    label 'linux-agents-xlarge'
  }

  options {
    timeout(time: 420, unit: 'MINUTES')
    buildDiscarder logRotator(
      artifactDaysToKeepStr: '',
      artifactNumToKeepStr: '',
      daysToKeepStr: '',
      numToKeepStr: '5')
    disableResume()
    disableConcurrentBuilds()
    ansiColor('xterm')
    copyArtifactPermission '*'
  }

  parameters {
    separator(name: 'dna-mobile-build-params', sectionHeader: 'docker params')
    booleanParam description: 'Skip docker image build, use pre-build image instead', name: 'USE_CACHE'
    separator(name: 'dna-mobile-build-params', sectionHeader: 'tests limit params')
    choice(
            choices: [
                    'qa',
                    'dev',
                    'uat',
                    'prod',
            ],
            description: 'Choose environment to run tests',
            name: 'ENVIRONMENT'
    )
    choice(
            choices: [
                    'Safari',
                    'Chrome',
                    'Firefox',
            ],
            description: 'Choose browser to run tests',
            name: 'BROWSER'
    )
    choice(
            choices: [
                    'ALL',
                    'smoke',
                    'regression',
            ],
            description: 'Choose set of tests',
            name: 'MARKER'
    )
    // Threads number is limited to number of existent accounts "success+autotester_dna<1…10>@simulator.amazonses.com"
    // Request more accounts to use more threads
    choice(
            choices: [
                    5,
                    1,
                    10
            ],
            description: 'Choose number of threads to run. Recommended to use <1> if you specify USER_EMAIL',
            name: 'THREADS'
    )
    string (
            defaultValue: '',
            description: 'User email for UAT testing. E.g. andrii.kolomiiets.sme@sonymusic.com',
            name: 'USER_EMAIL',
            trim: true
    )
    text defaultValue: '{"cookies":[{"name":"dna_refresh_token_uat","value":"YOUR_VALUE_HERE","domain":".dna.stream","path":"/"},{"name":"dna_bearer_token_uat","value":"","domain":".dna.stream","path":"/"}]}', description: 'Provide browser context for UAT testing', name: 'STATE_FILE'
    string (
            defaultValue: '',
            description: 'Limit check to these tests only',
            name: 'TESTS',
            trim: true
    )
    string (
            defaultValue: '',
            description: 'Copy allure report from this build',
            name: 'PREVIOUS_ALLURE_RESULTS_BUILD_NUMBER',
            trim: true
    )
  }

  environment {
    AWS_PROFILE           = "gdb-infra-dev"
    NOTIFICATIONS_CHANNEL = "#dna-test-reports"

    PYTEST_XDIST_WORKER = 'master'

    AUDIENCE       = "atlasum|no_mfa"
    CLIENT_ID      = "${getClientId(params.ENVIRONMENT)}"
    CLIENT_SECRET  = utility.getSecretValueByIdAndJsonPath('infra/jenkins/uitest/dna/AUTH0_CLIENT_SECRET', 'gdb-infra-dev', ".${params.ENVIRONMENT}")
    GRANT_TYPE     = "client_credentials"
    AUTH_HOST      = "${getAuthHostByEnv(params.ENVIRONMENT)}"
    AUTH_PROXY     = "${getAuthProxyByEnv(params.ENVIRONMENT)}"
    BROWSER        = "${params.BROWSER}"
    ENV_BASE_URL   = "${getEnvBaseUrlByEnv(params.ENVIRONMENT)}"
    NO_MFA         = "${getNoMfaByEnv(params.ENVIRONMENT)}"
    TARGET_API_URL = "${getTargetApiUrlByEnv(params.ENVIRONMENT)}"
    USER_EMAIL     = "${params.USER_EMAIL}"
    STATE_FILE     = "${params.STATE_FILE}"
    THREADS        = "${params.THREADS}"

    AWS_ACCOUNT_ID = '814622134907'
    AWS_REGION     = 'us-east-1'

    ECR_REGISTRY        = "${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com"
    ECR_REPOSITORY_NAME = 'dna/pytest'
    ECR_REGISTRY_URI    = "${ECR_REGISTRY}/${ECR_REPOSITORY_NAME}"

    REVISION = "${sh script: 'git rev-parse --short=8 HEAD', returnStdout: true}".trim()
  }

  stages {
    stage('Notify start') {
      steps {
        script {
          utility.slackNotify(
            currentBuild.currentResult,
            env.NOTIFICATIONS_CHANNEL,
            "started ${env.JOB_NAME} <${env.BUILD_URL}|Open>"
          )
        } /** end: script */
      } /** end: steps */
    } /** end: stage */

    stage('Build') {
      when {
        not { expression { return params.USE_CACHE } }
      }
      steps {
        sh label: 'build docker image', script: 'make docker/image/build'
      } /** end: steps */
    } /** end: stage */

    stage('Push') {
      when {
        allOf {
          not { expression { return params.USE_CACHE } }
          // branch 'master'
        }
      }
      steps {
        sh label: 'push docker image', script: 'make docker/image/push'
      } /** end: steps */
    } /** end: stage */

    stage('Pull') {
      when {
        allOf {
          expression { return params.USE_CACHE }
          // branch 'master'
        }
      }
      steps {
        sh label: 'pull docker image', script: 'make docker/image/pull'
      } /** end: steps */
    } /** end: stage */

    stage('Test') {
      stages{
        stage('Copy Allure report') {
          when {
            not { expression { return  params.PREVIOUS_ALLURE_RESULTS_BUILD_NUMBER.equals('') } }
          }
          steps {
            script {
              copyArtifacts filter: 'output/allure_report/*',
                            fingerprintArtifacts: true,
                            projectName: currentBuild.fullProjectName,
                            selector: specific("${params.PREVIOUS_ALLURE_RESULTS_BUILD_NUMBER}")
            }
          }
        }
        stage('Test') {
          steps {
            withDockerContainer(args: "--entrypoint=''", image: "${ECR_REGISTRY_URI}:${env.REVISION}") {
              script {
                sh label: 'crete a file', script: 'echo ${STATE_FILE} > state.json'
                sh label: 'list files', script: 'ls -ashil'

                ui_test_cmd = []
                ui_test_cmd << ('pytest')
                ui_test_cmd << ('--html=output/report.html')
                ui_test_cmd << ('--self-contained-html')
                ui_test_cmd << ('--alluredir=output/allure_report')
                ui_test_cmd << ('--reruns 2')
                ui_test_cmd << ("-n ${env.THREADS}")
                if (params.MARKER != 'ALL') {
                  ui_test_cmd << ("-m ${env.MARKER}")
                }
                if (params.TESTS != '') {
                  ui_test_cmd << ("src/tests/${params.TESTS}")
                } else {
                  ui_test_cmd << ('src/tests')
                }
                echo ui_test_cmd.join(' ')
                sh label: 'run ui tests', script: ui_test_cmd.join(" ")
              } /** end: script */
            } /** end: withDockerContainer */
          } /** end: steps */
          post {
            always {
              sh 'mkdir -p output/ && sudo chown ec2-user:ec2-user -R output/ && ls -l output/'
              script {
                publishHTML target: [
                              allowMissing         : false,
                              alwaysLinkToLastBuild: false,
                              keepAll              : true,
                              reportDir            : '',
                              reportFiles          : 'output/report.html',
                              reportName           : 'Selenoid report',
                            ]
                allure([
                  includeProperties: false,
                  jdk              : '',
                  properties       : [],
                  reportBuildPolicy: 'ALWAYS',
                  results          : [[path: 'output/allure_report']]
                ])
                archiveArtifacts artifacts: 'output/allure_report/*'
                script { testSummary = utility.getAllureTestSummary(env.BUILD_URL) }
              } /** end: script */
            } /** end: always */
          } /** end: post */
        } /** end: stage */
      } /** end: stages */
    } /** end: stage */
  } /** end: stages */
  post {
    success {
      script { utility.slackNotify('SUCCESS', env.NOTIFICATIONS_CHANNEL, 'ignored', testSummary) }
    } /** end: success */
    failure {
      script { utility.slackNotify('FAILURE', env.NOTIFICATIONS_CHANNEL, 'ignored', testSummary) }
    } /** end: unsuccessful */
    unstable {
      script { utility.slackNotify('UNSTABLE', env.NOTIFICATIONS_CHANNEL, 'ignored', testSummary) }
    } /** end: unsuccessful */
    always {
      script {
        utility.slackNotify(
          currentBuild.currentResult,
          env.NOTIFICATIONS_CHANNEL,
          "finished ${env.JOB_NAME} <${env.BUILD_URL}|Open>"
        )
      } /** end: script */
    } /** end: always */
  } /** end: post */
} /** end: pipeline */
