#!/usr/bin/env groovy

@Library('infraLib') _

pipeline {
    agent {
        label 'linux-agents'
    }
    options {
        ansiColor('xterm')
        disableConcurrentBuilds()
        authorizationMatrix([])
    }
    environment {
        PROJECT        = 'api'
        PROJECT_GROUP  = 'artistapp'
        VERSION        = octopus.getVersion(env.BRANCH_NAME,env.WORKSPACE)

        AWS_PROFILE    = 'gdb-artistapp-dev'
        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 = "${env.PROJECT_GROUP}/${env.PROJECT}"
        ECR_REGISTRY_URI    = "${env.ECR_REGISTRY}/${ECR_REPOSITORY_NAME}"

        OCTOPUS_PROJECT     = "sma.${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          = octopus.setDeploymentEnv(params.DEPLOY_ENV_CHOICE, env.PROJECT_GROUP, env.BRANCH_NAME)

        NOTIFICATIONS_CHANNEL = '#ama-deployments'
    }
    parameters {
        choice(
            choices: [
                'default',
                'dev',
                'qa',
                'stage',
                'prod',
                'skip_deployment'
            ],
            description: 'Set environment for deployment. Development by default',
            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 - overwrite 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'
        )
    }
    triggers {
        issueCommentTrigger('.*build me.*')
    }
    stages {
        stage('Validate Software Catalog Definition') {
            steps {
                library "jenkins-global-libraries@master"
                datadogSoftwareCatalogValidate()
            }
        }
        stage('Build') {
            steps {
                script { currentBuild.displayName = env.VERSION }
                sh label: 'build', script: '''
                  printf '{ "tag": "%s", "hash": "%s" }\n' `git describe || echo 'unknown'` `git rev-parse --short HEAD` > src/version.json
                  make docker/login 
                  make docker/image/build
                '''
            }
        }
        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/login
                          make docker/image/push
                        '''
                    } /** end: steps */
                } /** end: stage */
                stage('Upload documentation') {
                    when {
                        expression { return fileExists("${env.WORKSPACE}/docs") }
                    }
                    steps {
                        script {
                            documentation.upload(env.BRANCH_NAME, env.WORKSPACE)
                        } /** end: script */
                    } /** 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.deployRelease(env.OCTOPUS_PROJECT,env.DEPLOY_ENV,env.VERSION,env.OCTOPUS_CHANNEL)
                    } /** end: steps */
                } /** end: stage */
                stage('Publish Software Catalog Definition') {
                    when {
                        branch 'master'
                    }
                    steps {
                        datadogSoftwareCatalogPublish(fetchAdditionalMetadata: false)
                    }
                }
            } /** end: stages */
        } /** end: stage */
    }
    post {
        /* always {
            script {
                utility.slackNotify(currentBuild.currentResult, env.NOTIFICATIONS_CHANNEL)
            }
        } */
        cleanup {
            deleteDir()
        }
    }
}
