#!groovy
@Library('infraLib') _

def devicesList = apolloGoHelpers.supportedMobileDevices()

def app_url
def api_test_cmd
def ui_test_cmd
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 {
    booleanParam description: 'Skip docker image build, use pre-build image instead', name: 'USE_CACHE'
    separator(name: 'tri-mobile-build-params', sectionHeader: 'Mobile build parameters')
    string (
      defaultValue: 'RTI/pipelines/ama-frontend/development',
      description: 'Name of the job to copy artifacts from.',
      name: 'TARGET_JOB_NAME',
      trim: true
    )
    string (
      defaultValue: '',
      description: 'Number of the build to copy artifacts from.',
      name: 'TARGET_BUILD_NUMBER',
      trim: true
    )
    string (
      defaultValue: '',
      description: 'Application version',
      name: 'IOS_BUILD',
      trim: true
    )
    choice(
      choices: devicesList,
      description: 'Choice a device',
      name: 'IOS_DEVICE_VERSION'
    )
    string (
      defaultValue: '1.22.0',
      description: 'Appium version',
      name: 'APPIUM_VERSION',
      trim: true
    )
    choice(
      choices: [
        '5',
        '4',
        '3',
        '2',
        '1',
        '10',
        '9',
        '8',
        '7',
        '6',
      ],
      description: 'Choose a device',
      name: 'NUMBER_OF_PARALLEL_TESTS'
    )
    string (
      defaultValue: '',
      description: 'Limit check to these UI tests only',
      name: 'UI_TESTS',
      trim: true
    )
    string (
      defaultValue: '',
      description: 'Copy allure report from this build',
      name: 'PREVIOUS_ALLURE_RESULTS_BUILD_NUMBER',
      trim: true
    )
    string (
      defaultValue: '',
      description: 'Artist',
      name: 'ARTIST',
      trim: true
    )
    choice(
      choices: [
        'ALL',
        'smoke',
        'regression',
        'artist',
      ],
      description: 'Choose set of tests',
      name: 'MARKER'
    )
  }

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

    TARGET_API_URL = "https://qa-proxy.apollo.stream"
    TARGET_API_URL_PROD = 'https://proxy.apollo.stream'
    ENV_BASE_URL   = "False"
    SECRET_KEY     = "False"
    APP_NAME       = "INSIGHTS"

    AUTH0_CLIENT_ID     = utility.getSecretValueById('infra/jenkins/uitest/apollo/AUTH0_CLIENT_ID', env.AWS_PROFILE)
    AUTH0_CLIENT_ID_PROD = utility.getSecretValueById('infra/jenkins/uitest/apollo/AUTH0_CLIENT_ID_PROD', env.AWS_PROFILE)
    AUTH0_AUDIENCE      = 'https://apollo-private-api/'
    AUTH0_GRANT_TYPE    = 'http://auth0.com/oauth/grant-type/password-realm'
    AUTH0_REALM         = 'LevelDB'
    AUTH0_CLIENT_SECRET = utility.getSecretValueById('infra/jenkins/uitest/apollo/AUTH0_CLIENT_SECRET', env.AWS_PROFILE)
    AUTH0_HOST          = 'https://sme-dna.auth0.com/oauth/token'
    USER_EMAIL          = 'svidzya.w+4@gmail.com'
    USER_PASSWORD       = utility.getSecretValueById('infra/jenkins/uitest/USER_PASSWORD', env.AWS_PROFILE)
    USER_PASSWORD_PROD = utility.getSecretValueById('infra/jenkins/uitest/USER_PASSWORD_PROD', env.AWS_PROFILE)

    DELPHI_API_URL             = "https://delphi-api-ext.delphiplatform.io/"
    AUTH0_CLIENT_ID_DELPHI     = utility.getSecretValueById('infra/jenkins/uitest/apollo/AUTH0_CLIENT_ID_DELPHI', env.AWS_PROFILE)
    AUTH0_CLIENT_SECRET_DELPHI = utility.getSecretValueById('infra/jenkins/uitest/apollo/AUTH0_CLIENT_SECRET_DELPHI', env.AWS_PROFILE)
    AUTH0_CLIENT_SECRET_PROD = utility.getSecretValueById('infra/jenkins/uitest/apollo/AUTH0_CLIENT_SECRET_PROD', env.AWS_PROFILE)
    AUTH0_GRANT_TYPE_DELPHI    = "client_credentials"

    AUTH0_REALM_PROD = 'MergedUsersDB'
    AUTH0_SCOPE_PROD = 'openid profile'
    AUTH0_HOST_PROD  = 'https://prod-dna-apps.auth0.com/oauth/token'

    NOTIFICATIONS_EMAIL    = "False"
    NOTIFICATIONS_PASSWORD = "False"

    MYSQL_DB_NAME = 'False'
    MYSQL_DB_HOST = 'False'
    MYSQL_DB_USER = 'False'
    MYSQL_DB_PASS = 'False'

    SUPERUSER_EMAIL    = "autoqa2@example.com"
    SINGLEUSER_EMAIL   = "autoqa1@example.com"
    SUPERUSER_PASSWORD = utility.getSecretValueById('infra/jenkins/uitest/SUPERUSER_PASSWORD', 'gdb-infra-dev')

    SELENOID_HOST    = "False"
    JENKINS_JOB_NAME = "${env.JOB_NAME}"
    APPIUM_VERSION   = "${params.APPIUM_VERSION}"

    BROWSERSTACK_APP_USER = utility.getSecretValueById('infra/jenkins/browserstack/BROWSERSTACK_USERNAME', 'gdb-infra-dev')
    BROWSERSTACK_APP_KEY  = utility.getSecretValueById('infra/jenkins/browserstack/BROWSERSTACK_ACCESS_KEY', 'gdb-infra-dev')

    NUMBER_OF_PARALLEL_TESTS = "${params.NUMBER_OF_PARALLEL_TESTS}"

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

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

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

    ARTIST = "${params.ARTIST}"
    MARKER = "${params.MARKER}"
  }

  stages {
    stage('Notify start') {
      steps {
        script {
          utility.slackNotify(
            currentBuild.currentResult,
            env.NOTIFICATIONS_CHANNEL,
            "started ${env.JOB_NAME} <${env.BUILD_URL}|Open>"
          )
          currentBuild.description = """IOS_BUILD: ${params.IOS_BUILD}
MARKER: ${env.MARKER}
ARTIST: ${env.ARTIST}
          """
        } /** 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('UI test') {
      when {
        allOf {
          not { expression { return  params.IOS_BUILD.equals('') } }
        }
      }
      environment {
        BROWSER_NAME        = 'browserstack_ios'
        SELENIUM_TIMEOUT    = 20
        SELENIUM_ENV        = 'mobile_bs'
        PYTEST_XDIST_WORKER = 'false'
        SELENIUM_HEADLESS   = 'false'
        CHROMEDRIVER_PATH   = 'path'
      }
      stages {
        stage('Upload artifact') {
          stages {
            stage('Copy Artifact') {
              steps {
                script {
                  copyArtifacts filter: '',
                                fingerprintArtifacts: true,
                                projectName: "${params.TARGET_JOB_NAME}",
                                selector: specific("${params.TARGET_BUILD_NUMBER}")
                }
              }
            }
            stage('Upload to BS') {
              environment {
                FILE_PATH = "${sh script: 'ls artifacts/*.ipa', returnStdout: true}".trim()
              }
              steps {
                script {
                  app_url = sh(
                      label: 'Upload artifact',
                      returnStdout: true,
                      script: """
                        set +x # suppress debug output
                        curl -q -u \"${env.BROWSERSTACK_APP_USER}:${env.BROWSERSTACK_APP_KEY}\" \
                          -X POST \"https://api-cloud.browserstack.com/app-automate/upload\" \
                          -F \"file=@${env.FILE_PATH}\" | jq -r '.app_url'
                      """
                  )
                  echo "${app_url}"
                } /** end: script */
              } /** end: steps */
            } /** end: stage */
          } /** end: stages */
        } /** end: stage */
        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') {
          environment {
            IOS_BUILD    = "${params.IOS_BUILD}"
            IOS_APP_PATH = "${app_url}"
            IOS_DEVICE   = "${params.IOS_DEVICE_VERSION.split(',').first()}"
            IOS_VERSION  = "${params.IOS_DEVICE_VERSION.split(',').last().replace('iOS ', '')}"
          }
          steps {
            withDockerContainer(args: "--entrypoint=''", image: "${ECR_REGISTRY_URI}:${env.REVISION}") {
              script {
                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 1')
                ui_test_cmd << ("-n ${env.NUMBER_OF_PARALLEL_TESTS}")
                if (params.MARKER != 'ALL') {
                  ui_test_cmd << ("-m ${env.MARKER}")
                }
                if (params.UI_TESTS != '') {
                  ui_test_cmd << ("src/tests/gui/${params.UI_TESTS}")
                } else {
                  ui_test_cmd << ('src/tests/gui')
                }
                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 */
