#!groovy

@Library('infraLib') _

def bumpVersionBranch = 'master'

def setDefaultDeployEnv(branch) {
  switch(branch) {
    case "master":
    case ~/release.*$/:
    case ~/hotfix.*$/:
      return ("stage")
    default:
      return ("dev")
  }
}

def setDeploymentEnv(deployEnvChoice, branch) {
  switch(deployEnvChoice) {
    case "default":
      return setDefaultDeployEnv(branch)
    case "skip_deployment":
      return deployEnvChoice
    default:
      return (deployEnvChoice)
  }
}

pipeline {
  agent {
    label 'linux-agents'
  }
  options {
    ansiColor('xterm')
    disableConcurrentBuilds()
    timeout(60)
    timestamps()
    buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '30')
  }
  environment {
    PROJECT        = 'atlas-um-integration-example'
    PROJECT_GROUP  = 'core'

    AWS_PROFILE    = 'gdb-core-dev'
    AWS_ACCOUNT_ID = '582412345909'
    AWS_REGION     = 'us-east-1'

    ECR_REGISTRY        = "${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com"
    ECR_REPOSITORY_NAME = "${PROJECT_GROUP}/${PROJECT}"
    ECR_REGISTRY_URI    = "${env.ECR_REGISTRY}/${ECR_REPOSITORY_NAME}"

    OCTOPUS_PROJECT     = "${env.PROJECT_GROUP}.${env.PROJECT}"
    OCTOPUS_CLI_SERVER  = 'https://octopus.delphi.zone'
    OCTOPUS_CLI_API_KEY = utility.getSecretValueById('infra/jenkins/octopus_api_key', 'gdb-delphi-dev')
    OCTOPUS_CHANNEL     = octopus.setOctoChannel(env.BRANCH_NAME)
    DEPLOY_ENV          = setDeploymentEnv(params.DEPLOY_ENV_CHOICE, env.BRANCH_NAME)
    VERSION             = octopus.getVersion(env.BRANCH_NAME,env.WORKSPACE)

    NOTIFICATIONS_CHANNEL = '#core-deployments'
  }

  parameters {
    separator(name: 'separator-atlas-um-integration-example-deployment', sectionHeader: 'Deployment parameters')
    choice(
      choices: [
        'default',
        'dev',
        'qa',
        'stage',
        'uat',
        'prod',
        'skip_deployment'
      ],
      description: 'Set environment for deployment.',
      name: 'DEPLOY_ENV_CHOICE'
    )
    choice(
      choices: [
        'default',
        'yes',
        'no'
      ],
      description: 'By default deploy is only triggered for develop/release/master branch',
      name: 'TRIGGER_DEPLOY'
    )
    choice(
      choices: [
        'error',
        'overwrite',
        'skip_build'
      ],
      description: "Docker image upload mode - ovewrite if the image with such tag already exists, raise error if exists, or skip build part if exists.",
      name: 'IMAGE_UPLOAD_MODE'
    )
    choice(
      choices: [
        'no',
        'yes'
      ],
      description: "Don't raise errors in case release already exists",
      name: 'SKIP_RELEASE_CREATION'
    )
  }

  stages {
    stage('BuildWrapper') {
      environment {
        VERSION = octopus.getVersion(env.BRANCH_NAME,env.WORKSPACE)
      }

      stages {
        stage('Build') {
          options {
            retry(2)
          }
          steps {
            script { currentBuild.displayName = env.VERSION }
            sh label: 'build', script: '''
                make docker/image/build
            '''
          } /** end: steps */
        } /** end: stage */

        stage('Deploy') {
          when {
            anyOf {
              branch 'master'
              branch 'develop'
              expression { return params.TRIGGER_DEPLOY.equals('yes') }
            }
          }
          stages {
            stage('Check version') {
              when { expression { return params.IMAGE_UPLOAD_MODE == 'error' && octopus.ecrImageTagExists(env.VERSION,env.ECR_REPOSITORY_NAME,env.AWS_PROFILE) }}
              steps { error "Image with ${env.VERSION} version tag already exists. To ignore this error set IMAGE_UPLOAD_MODE parameter to overwrite or skip_build"}
            } /** end: stage */
            stage('Push to ECR') {
              when {
                expression { return params.IMAGE_UPLOAD_MODE == 'overwrite' || !octopus.ecrImageTagExists(env.VERSION,env.ECR_REPOSITORY_NAME,env.AWS_PROFILE) }
              }
              steps {
                sh label: 'push', script: '''
                  make docker/image/push
                '''
              } /** end: steps */
            } /** end: stage */
            stage('Create a release in octopus') {
              //Check if release already exists. If it does, raise error or skip it, based on given param
              when {
                expression { return params.SKIP_RELEASE_CREATION.equals('no') || !octopus.releaseExists(env.OCTOPUS_PROJECT,env.VERSION) }
              }
              steps {
                echo octopus.createRelease(env.OCTOPUS_PROJECT,env.VERSION,env.OCTOPUS_CHANNEL)
              } /** end: steps */
            } /** end: stage */
            stage('Deploy release in octopus') {
              when {
                not { expression { return env.DEPLOY_ENV.equals('skip_deployment') } }
              }
              steps {
                echo octopus.deployReleaseToAllTenants(env.OCTOPUS_PROJECT,env.DEPLOY_ENV,env.VERSION,env.OCTOPUS_CHANNEL)
              } /** end: steps */
            } /** end: stage */
          } /** end: stages */
        } /** end: stage */
      } /** end; stages */
      post {
        always {
          sh label: 'fix permissions', script: "sudo chown \$(whoami):\$(whoami) -R ${env.WORKSPACE}"
          script {
            utility.slackNotify(currentBuild.currentResult, env.NOTIFICATIONS_CHANNEL)
          }
        }
        cleanup {
          deleteDir()
        }
      } /** end: post */
    } /** end: stage */
  } /** end: stages */
} /* end: pipeline */
