@Library('infraLib') _

List<Map<String, String>> configMapping = [
  [source: 'dsp-complete-criteria.json',           dest: 'dsp-complete-criteria.json'],
  [source: 'dsp-specific-settings.json',           dest: 'dsp-specific-settings.json'],
  [source: 'dsp_config.json',                      dest: 'dsp_config.json'],
  [source: 'apps-etl-config.json',                 dest: 'apps-etl-config.json'],
  [source: 'apps-etl-versions.json',               dest: 'apps-etl-versions.json'],
  [source: 'exploration-etl-config.json',          dest: 'exploration-etl-config.json'],
  [source: 'exploration-dsp-config.json',          dest: 'exploration-dsp-config.json'],
  [source: 'appreciationengine/mapping.json',      dest: 'appreciationengine/mapping.json'],
  [source: 'apple-music-charts/mapping.json',      dest: 'apple-music/charts/playlist_mapping.json'],
  [source: 'dtf/staging_to_public_settings.json',  dest: 'dtf/staging_to_public_settings.json'],
  [source: 'dtf/materialized_views.json',          dest: 'dtf/materialized_views.json'],
  [source: 'dtf/dapd_importer_lambda_config.json', dest: 'dtf/dapd_importer_lambda_config.json'],
  [source: 'dtf/api_stored_procedures.json',       dest: 'dtf/api_stored_procedures.json'],
  [source: 'dtf/dbx_config.json',                  dest: 'dtf/dbx_config.json'],
  [source: 'brandwatch_config.json',               dest: 'brandwatch_config.json'],
  [source: 'apollo_dapd_config.json',              dest: 'apollo_dapd_config.json'],
  [source: 'gras-queries',                         dest: 'gras-queries']
]

List<Map<String, String>> configsToDeploy = null

pipeline {
  agent {
    label 'linux-agents'
  }
  options { disableConcurrentBuilds() }
  environment {
    NOTIFICATIONS_CHANNEL   = 'delphi-slz-cicd-alerts'
  }
  parameters {
    choice(
      choices: [
        'Automatic choice',
        'dsp-complete-criteria.json',
        'dsp-specific-settings.json',
        'dsp_config.json',
        'apps-etl-config.json',
        'apps-etl-versions.json',
        'exploration-etl-config.json',
        'exploration-dsp-config.json',
        'appreciationengine/mapping.json',
        'apple-music-charts/mapping.json',
        'dtf/staging_to_public_settings.json',
        'dtf/materialized_views.json',
        'dtf/dapd_importer_lambda_config.json',
        'dtf/api_stored_procedures.json',
        'dtf/dbx_config.json',
        'brandwatch_config.json',
        'apollo_dapd_config.json',
        'gras-queries',
        'ALL'
      ],
      description: 'Deploy specific or all configs. ',
      name: 'CONFIG_TO_DEPLOY'
    )
    booleanParam(name: 'DEPLOY_TO_DEV', defaultValue: true, description: 'Whether or not to deploy to dev.')
    booleanParam(name: 'DEPLOY_TO_QA', defaultValue: true, description: 'Whether or not to deploy to qa.')
    booleanParam(name: 'DEPLOY_TO_STAGING', defaultValue: false, description: 'Whether or not to deploy to staging.')
    booleanParam(name: 'DEPLOY_TO_PROD', defaultValue: false, description: 'Whether or not to deploy to prod.')

  }
  stages {
    stage('Define configs to deploy') {
      steps {
        script {
          switch(params.CONFIG_TO_DEPLOY) {
            case 'ALL':
              configsToDeploy = configMapping
              break
            case 'Automatic choice':
              def changedFiles = pythonPackage_v2.getChangesLastOrPR()
              println('Changed files list:')
              changedFiles.each {println it}
              configsToDeploy = configMapping.findAll { item -> changedFiles.any { p -> p.contains(item.source) }}
              break
            default:
              configsToDeploy = configMapping.findAll { params.CONFIG_TO_DEPLOY in it.source  }
          }
          println('Configs to deploy:')
          configsToDeploy.each {println it}
        }
      }
    }
    stage('Deploy to dev') {
      when {
        expression { params.DEPLOY_TO_DEV == true }
      }
      steps {
        script {
          configsToDeploy.each {deployToEnv('dev', it.source, it.dest)}
        }
      }
    }
    stage('Deploy to QA') {
      when {
        expression { params.DEPLOY_TO_QA == true }
      }
      steps {
        script {
          configsToDeploy.each {deployToEnv('qa', it.source, it.dest)}
        }
      }
    }
    stage('Deploy to staging') {
      when {
        allOf {
          branch 'master'
          expression { params.DEPLOY_TO_STAGING == true }
        }
      }
      steps {
        script {
          configsToDeploy.each {deployToEnv('stage', it.source, it.dest)}
        }
      }
    }
    stage('Deploy to prod') {
      when {
        allOf {
          branch 'master'
          expression { params.DEPLOY_TO_PROD == true }
        }
      }
      steps {
        script {
          configsToDeploy.each {deployToEnv('prod', it.source, it.dest)}
        }
      }
    }
  }
  post {
    always {
      sh "sudo chown -R ec2-user:ec2-user ${env.WORKSPACE}"
    }
    success {
      script {
        if (currentBuild.getPreviousBuild() &&
            currentBuild.getPreviousBuild().getResult().toString() != "SUCCESS") {
          utility.slackNotifyMainBranches(currentBuild.currentResult, env.NOTIFICATIONS_CHANNEL)
        }
      }
    }
    failure {
      script {
        utility.slackNotifyMainBranches(currentBuild.currentResult, env.NOTIFICATIONS_CHANNEL)
      }
    }
    cleanup {
      deleteDir()
    }
  }
}

def deployToEnv(environment, source, destination) {
  def aws_profile = 'gdb-delphi-dev'
  if (environment == 'prod') {
    aws_profile = 'gdb-delphi-prod'
  }
  def bucket = "${environment}-delphi-configs"
  if (source == 'gras-queries') {
    sh(script: "aws s3 cp --profile ${aws_profile} --recursive ${source} s3://${bucket}/${destination}")
  } else {
    sh(script: "aws s3 cp --profile ${aws_profile} configs/${environment}/${source} s3://${bucket}/${destination}")
  }
}
