#!groovy
@Library('infraLib') _

def npm(String command) {
   dockerRun("npm run ${command}")
}

def dockerRun(String command) {
   sh script: """
    docker run \
    --env AWS_PROFILE \
    --env EXPO_TOKEN \
    --env SENTRY_AUTH_TOKEN \
    --env LOCAL_BUILD_TAG \
    --env LOCAL_GIT_COMMIT \
    --env IMAGE_TAG \
    --env RELEASE_ENV \
    --env FRESHDESK_API_KEY \
    --env AMPLITUDE_API_KEY \
    --env AUTH0_CLIENT_ID \
    --env EXPO_APPLE_APP_SPECIFIC_PASSWORD \
    --env EXPO_APPLE_APP_SPECIFIC_EMAIL \
    artistapp:${env.IMAGE_TAG} ${command}
  """
}

def easBuildInsideDockerContainer(String tag, String platform, String profile) {
  docker.image("artistapp:${tag}").inside {
    res = sh returnStdout: true, script: """
      cd /usr/src/app && \
      npm run --silent eas build -- \
        --platform ${platform} \
        --profile ${profile} \
        --non-interactive \
        --skip-project-configuration \
        --json
    """
    echo res
    obj = readJSON text: res
    obj.each {
      url = it.artifacts.buildUrl
      fileName = url.split('/')[-1].trim()
      sh script: """
        mkdir -p artifacts/;
        curl -q -L -o artifacts/${fileName} ${url};
      """
    } /** end: each */
  } /** end: inside */
}

def getReleaseEnv(build_type) {
  switch (build_type) {
    case 'IOS_BUILD_DEV':
      return 'automation_dev'
    case 'IOS_SIMULATOR_BUILD_DEV':
      return 'automation_simulator_dev'
    case 'IOS_BUILD_STG':
      return 'automation_stage'
    case 'IOS_SIMULATOR_BUILD_STG':
      return 'automation_simulator_stage'
    case 'IOS_BUILD_PROD':
      return 'automation_prod'
    case 'IOS_SIMULATOR_BUILD_PROD':
      return 'automation_simulator_prod'
    default:
      return 'automation_dev'
  }
}

pipeline {
  agent {
    label 'linux-agents-xlarge'
  }

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

  parameters {
    booleanParam(
      defaultValue: false,
      description: 'FORCE PUBLISH',
      name: 'FORCE_PUBLISH'
    )
    choice(
      name: 'FORCE_BUILD',
      choices: [
        'Please make a choice',
        'ANDROID_BUILD',
        'IOS_BUILD_DEV',
        'IOS_SIMULATOR_BUILD_DEV',
        'IOS_BUILD_STG',
        'IOS_SIMULATOR_BUILD_STG',
        'IOS_BUILD_PROD',
        'IOS_SIMULATOR_BUILD_PROD',
      ],
      description: 'Force a build.'
    )
  }

  environment {
    AWS_PROFILE       = 'gdb-infra-dev'
    EXPO_TOKEN        = utility.getSecretValueById('infra/jenkins/rti/common/EXPO_BOT_USER_TOKEN', env.AWS_PROFILE)
    SENTRY_AUTH_TOKEN = utility.getSecretValueById('infra/jenkins/rti/common/SENTRY_AUTH_TOKEN', env.AWS_PROFILE)
    LOCAL_BUILD_TAG   = env.BUILD_TAG.replace('/', '-')
    LOCAL_GIT_COMMIT  = env.GIT_COMMIT.replace('/', '-')
    IMAGE_TAG         = "${env.LOCAL_BUILD_TAG}-${env.LOCAL_GIT_COMMIT}"
  }
  
  stages {
    stage('Build') {
      steps {
        sh "docker build -t artistapp:${env.IMAGE_TAG} ."
      }
    }

    stage('Test') {
      environment {
        RELEASE_ENV       = 'test'
        FRESHDESK_API_KEY = 'test'
        AMPLITUDE_API_KEY = 'test'
        AUTH0_CLIENT_ID   = 'test'
      }
      steps {
        npm "test:ci"
      }
    }

    stage('Lint') {
      steps {
        npm "lint"
      }
    }

    stage('Deploy') {
      stages {
        stage('development') {
          when {
            anyOf {
              branch 'development'
              expression { return params.FORCE_PUBLISH }
            }
          }
          environment {
            RELEASE_ENV       = 'development'
            FRESHDESK_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/FRESHDESK_API_KEY", env.AWS_PROFILE)
            AMPLITUDE_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/AMPLITUDE_API_KEY", env.AWS_PROFILE)
            AUTH0_CLIENT_ID   = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/AUTH0_CLIENT_ID", env.AWS_PROFILE)
          }
          steps {
            npm "publish:development"
          }
        }
        stage('preview') {
          when {
            allOf {
              branch 'production-v3'
              expression { return params.FORCE_BUILD == 'Please make a choice' }
            }
          }
          environment {
            RELEASE_ENV                      = 'preview'
            FRESHDESK_API_KEY                = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/FRESHDESK_API_KEY", env.AWS_PROFILE)
            AMPLITUDE_API_KEY                = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/AMPLITUDE_API_KEY", env.AWS_PROFILE)
            AUTH0_CLIENT_ID                  = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/AUTH0_CLIENT_ID", env.AWS_PROFILE)
            EXPO_APPLE_APP_SPECIFIC_PASSWORD = utility.getSecretValueById("infra/jenkins/rti/${env.RELEASE_ENV}/EXPO_APPLE_APP_SPECIFIC_PASSWORD", env.AWS_PROFILE)
            EXPO_APPLE_APP_SPECIFIC_EMAIL    = utility.getSecretValueById("infra/jenkins/rti/${env.RELEASE_ENV}/EXPO_APPLE_APP_SPECIFIC_EMAIL", env.AWS_PROFILE)
          }
          stages {
            stage ('Publish:Preview') {
              steps {
                npm "publish:preview"
              } /** end: steps */
            } /** end: stage */
            stage('Build:All:Production') {
              steps {
                script {
                  easBuildInsideDockerContainer(env.IMAGE_TAG, 'all', 'production')
                } /** end: script */
              } /** end: steps */
            } /** end: stage */
            stage('Trigger Test build') {
              steps {
                build job: '/RTI/RTIBuildWrapper',
                      wait: false,
                      propagate: true,
                      parameters: [
                        listGitBranches(name: 'RTI_BRANCH', value: 'refs/heads/production-v3'),
                        string(name: 'FORCE', value: 'IOS_BUILD_PROD'),
                        string(name: 'MARKER', value: 'smoke')
                      ]
              } /** end: steps */
            } /** end: stage */
          } /** end: stages */
        } /** end: stage */
        stage('production') {
          when {
            tag pattern: "^v\\d+\\.\\d+\\.\\d+\$", comparator: "REGEXP"
          }
          options {
            timeout(time: 30, unit: 'MINUTES')
          }
          environment {
            RELEASE_ENV       = 'production'
            FRESHDESK_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/FRESHDESK_API_KEY", env.AWS_PROFILE)
            AMPLITUDE_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/AMPLITUDE_API_KEY", env.AWS_PROFILE)
            AUTH0_CLIENT_ID   = utility.getParameterValueByName("/infra/jenkins/rti/${env.RELEASE_ENV}/AUTH0_CLIENT_ID", env.AWS_PROFILE)
          }
          steps {
            input "Publish to production-v3?"
            npm "publish:production"
          }
        }
        stage('automation') {
          when {
            not { expression { return params.FORCE_BUILD == 'Please make a choice' } }
          }
          environment {
            RELEASE_ENV       = getReleaseEnv(params.FORCE_BUILD)
            FRESHDESK_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/automation/FRESHDESK_API_KEY", env.AWS_PROFILE)
            AMPLITUDE_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/automation/AMPLITUDE_API_KEY", env.AWS_PROFILE)
            AUTH0_CLIENT_ID   = utility.getParameterValueByName("/infra/jenkins/rti/automation/AUTH0_CLIENT_ID", env.AWS_PROFILE)
          }
          stages {
            stage ('Android') {
              when {
                expression { return params.FORCE_BUILD == 'ANDROID_BUILD' }
              }
              steps {
                script {
                  easBuildInsideDockerContainer(env.IMAGE_TAG, 'android', 'automation_dev')
                } /** end: script */
              } /** end: steps */
            } /** end: stage */
            stage('dev') {
              when {
                expression { return env.RELEASE_ENV.endsWith('dev') }
              }
              environment {
                FRESHDESK_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/development/FRESHDESK_API_KEY", env.AWS_PROFILE)
                AMPLITUDE_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/development/AMPLITUDE_API_KEY", env.AWS_PROFILE)
                AUTH0_CLIENT_ID   = utility.getParameterValueByName("/infra/jenkins/rti/development/AUTH0_CLIENT_ID", env.AWS_PROFILE)
              }
              parallel {
                stage ('IOS DEV') {
                  when {
                    expression { return params.FORCE_BUILD == 'IOS_BUILD_DEV' }
                  }
                  steps {
                    script {
                      easBuildInsideDockerContainer(env.IMAGE_TAG, 'ios', 'automation_dev')
                    } /** end: script */
                  } /** end: steps */
                } /** end: stage */
                stage ('IOS Simulator DEV') {
                  when {
                    expression { return params.FORCE_BUILD == 'IOS_SIMULATOR_BUILD_DEV' }
                  }
                  steps {
                    script {
                      easBuildInsideDockerContainer(env.IMAGE_TAG, 'ios', 'automation_simulator_dev')
                    } /** end: script */
                  } /** end: steps */
                } /** end: stage */
              }
            }
            stage('staging') {
              when {
                expression { return env.RELEASE_ENV.endsWith('stage') }
              }
              environment {
                FRESHDESK_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/production/FRESHDESK_API_KEY", env.AWS_PROFILE)
                AMPLITUDE_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/production/AMPLITUDE_API_KEY", env.AWS_PROFILE)
                AUTH0_CLIENT_ID   = utility.getParameterValueByName("/infra/jenkins/rti/production/AUTH0_CLIENT_ID", env.AWS_PROFILE)
              }
              parallel {
                stage ('IOS STG') {
                  when {
                    expression { return params.FORCE_BUILD == 'IOS_BUILD_STG' }
                  }
                  steps {
                    script {
                      easBuildInsideDockerContainer(env.IMAGE_TAG, 'ios', 'automation_stage')
                    } /** end: script */
                  } /** end: steps */
                } /** end: stage */
                stage ('IOS Simulator STG') {
                  when {
                    expression { return params.FORCE_BUILD == 'IOS_SIMULATOR_BUILD_STG' }
                  }
                  steps {
                    script {
                      easBuildInsideDockerContainer(env.IMAGE_TAG, 'ios', 'automation_simulator_stage')
                    } /** end: script */
                  } /** end: steps */
                } /** end: stage */
              }
            }
            stage('prod') {
              when {
                expression { return env.RELEASE_ENV.endsWith('prod') }
              }
              environment {
                FRESHDESK_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/preview/FRESHDESK_API_KEY", env.AWS_PROFILE)
                AMPLITUDE_API_KEY = utility.getParameterValueByName("/infra/jenkins/rti/preview/AMPLITUDE_API_KEY", env.AWS_PROFILE)
                AUTH0_CLIENT_ID   = utility.getParameterValueByName("/infra/jenkins/rti/preview/AUTH0_CLIENT_ID", env.AWS_PROFILE)
              }
              parallel {
                stage ('IOS PROD') {
                  when {
                    expression { return params.FORCE_BUILD == 'IOS_BUILD_PROD' }
                  }
                  steps {
                    script {
                      easBuildInsideDockerContainer(env.IMAGE_TAG, 'ios', 'automation_prod')
                    } /** end: script */
                  } /** end: steps */
                } /** end: stage */
                stage ('IOS Simulator PROD') {
                  when {
                    expression { return params.FORCE_BUILD == 'IOS_SIMULATOR_BUILD_PROD' }
                  }
                  steps {
                    script {
                      easBuildInsideDockerContainer(env.IMAGE_TAG, 'ios', 'automation_simulator_prod')
                    } /** end: script */
                  } /** end: steps */
                } /** end: stage */
              }
            }
          }
          post {
            success {
              archiveArtifacts artifacts: 'artifacts/*',
                               fingerprint: true,
                               followSymlinks: false,
                               onlyIfSuccessful: true
            } /** end: success */
          } /** end: post */
        } /** end: stage */
      } /** end: stages */
    } /** end: stage */
  } /** end: stages */
} /** end: pipeline */
