#!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 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 */
}

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',
        'IOS_SIMULATOR_BUILD'
      ],
      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'
        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'
            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 {
            branch 'production-v3'
          }
          environment {
            RELEASE_ENV                      = 'preview'
            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)
          }
          steps {
            npm "publish:preview"
            script {
              easBuildInsideDockerContainer(env.IMAGE_TAG, 'all', 'production')
            } /** end: script */
            // npm "submit:ios"
          }
        }
        stage('production') {
          when {
            tag pattern: "^v\\d+\\.\\d+\\.\\d+\$", comparator: "REGEXP"
          }
          options {
            timeout(time: 30, unit: 'MINUTES')
          }
          environment {
            RELEASE_ENV       = 'production'
            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       = "automation"
            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)
          }
          parallel {
            stage ('Android') {
              when {
                expression { return params.FORCE_BUILD == 'ANDROID_BUILD' }
              }
              steps {
                script {
                  easBuildInsideDockerContainer(env.IMAGE_TAG, 'android', 'automation')
                } /** end: script */
              } /** end: steps */
            } /** end: stage */
            stage ('IOS') {
              when {
                expression { return params.FORCE_BUILD == 'IOS_BUILD' }
              }
              steps {
                script {
                  easBuildInsideDockerContainer(env.IMAGE_TAG, 'ios', 'automation')
                } /** end: script */
              } /** end: steps */
            } /** end: stage */
            stage ('IOS Simulator') {
              when {
                expression { return params.FORCE_BUILD == 'IOS_SIMULATOR_BUILD' }
              }
              steps {
                script {
                  easBuildInsideDockerContainer(env.IMAGE_TAG, 'ios', 'automation_simulator')
                } /** end: script */
              } /** end: steps */
            } /** end: stage */
          } /** end: parallel */
          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 */
