#!groovy

@Library('infraLib') _

def BRANCHES_TO_DEPLOY = [
  "master", "develop", "release",
  "qa", "uat", "production"
]

pipeline {
  agent {
    label 'linux-agents'
  }
  options {
    ansiColor('xterm')
    disableConcurrentBuilds()
  }
  environment {
    DEPLOY_TO_TEST       = "${params.DEPLOY_TO_TEST || utility.getGithubComment() == 'deploy me'}"
    ENV_PREFIX           = "${env.DEPLOY_TO_TEST == 'true' ? 'dev' : apolloApiHelpers.getEnvPrefixByBranch(env.BRANCH_NAME)}"
    PROJECT              = "${env.DEPLOY_TO_TEST == 'true' ? 'api-test' : apolloApiHelpers.getProjectNameByBranchName(env.BRANCH_NAME)}"
    PROJECT_GROUP        = "apollo"
    REPOSITORY           = "apollo-api"
    CLUSTER              = "${apolloApiHelpers.getClusterName(env.BRANCH_NAME, env.ENV_PREFIX, env.PROJECT_GROUP)}"
    SERVICE              = "${env.ENV_PREFIX}-${env.PROJECT_GROUP}-${env.PROJECT}"
    TASK_DEF             = "${env.ENV_PREFIX}-${env.PROJECT_GROUP}-${env.PROJECT}"
    TAG                  = "${env.DEPLOY_TO_TEST == 'true' ? 'test' : env.BRANCH_NAME}"
    ECR                  = "${params.ECR}"
    AWS_PROFILE          = "${apolloApiHelpers.getAWSProfileNameByBranchName(env.BRANCH_NAME)}"
    COMPOSE_PROJECT_NAME = "apollo-api-${env.BUILD_NUMBER}"

    DEPLOYMENT_NOTIFICATIONS_CHANNEL = '#apollo-deployments'
  }

  parameters {
    string(name: 'ECR', defaultValue: '475275892927.dkr.ecr.us-east-1.amazonaws.com', description: 'Docker images repository.')
    booleanParam(name: 'DEPLOY_TO_TEST', defaultValue: false, description: 'Deploy this build to test environment')
  }

  triggers {
    issueCommentTrigger('.*build me.*|.*deploy me.*')
  }

  stages {
    stage('Build') {\
      steps {
        echo "Using tag ${params.ECR}/${env.REPOSITORY}:${env.TAG}"
        echo "PG - ${env.PROJECT_GROUP} | ENV - ${env.ENV_prefix} | Project - ${env.PROJECT} | Force build - ${env.FORCE_BUILD}"
        echo "Deploy - ${env.DEPLOY_TO_TEST} | GITHUB_COMMENT - ${utility.getGithubComment()}"
        echo "service ${env.SERVICE} task-definition ${env.TASK_DEF} cluster ${env.CLUSTER}"
        sh "env"
        sh "cp .env.sample .env"
        sh "make docker/build"
      }
    } /* end: stage */

    stage('Unit tests') {
      steps {
        echo "Run unit tests"
        sh "make test"
      }
      post {
        always {
          sh "sudo chown \$(whoami):\$(whoami) -R ${env.WORKSPACE}"
          junit allowEmptyResults: false, testResults: "report.xml"
          cobertura autoUpdateHealth: false,
                    autoUpdateStability: false,
                    coberturaReportFile: 'coverage.xml',
                    conditionalCoverageTargets: '98, 70, 70',
                    failUnhealthy: false,
                    failUnstable: false,
                    lineCoverageTargets: '98, 70, 70',
                    maxNumberOfBuilds: 0,
                    methodCoverageTargets: '100, 70, 70',
                    onlyStable: false,
                    zoomCoverageChart: false
          sh "make docker-compose/down"
        }
      }
    } /* end: stage */

    stage('Check code style') {
      steps {
        echo "Check codestyle"
        sh "make checkstyle"
      }
    } /* end: stage */

    stage('Security check') {
      steps {
        echo "Security check"
        sh "make security"
      }
    } /* end: stage */

    stage('Upload image') {
      when {
        anyOf {
          expression { return env.BRANCH_NAME =~ /^release*&/ }
          expression { return BRANCHES_TO_DEPLOY.contains(env.BRANCH_NAME) }
          expression { return env.DEPLOY_TO_TEST.toBoolean() }
        }
      }
      environment {
        AWS_PROFILE = "gdb-delphi-dev"
      }
      steps {
        sh "make docker/push"
      }
    } /* end: stage */

    stage('Update ECS service') {
      when {
        anyOf {
          expression { return env.BRANCH_NAME =~ /^release*&/ }
          expression { return BRANCHES_TO_DEPLOY.contains(env.BRANCH_NAME) }
          expression { return env.DEPLOY_TO_TEST.toBoolean() }
        }
      }
      steps {
        slackSend channel: "${env.DEPLOYMENT_NOTIFICATIONS_CHANNEL}",
          color: 'warning',
          iconEmoji: ':rocket:',
          username: 'Deploy',
          message: "started deployment for ${env.JOB_NAME} <${env.BUILD_URL}|Open>"
        sh "aws ecs update-service --service ${env.SERVICE} --force-new-deployment --task-definition ${env.TASK_DEF} --cluster ${env.CLUSTER}"
        sh "aws ecs wait services-stable --service ${env.SERVICE} --cluster ${env.CLUSTER}"
      }
      post {
        success {
          slackSend channel: "${env.DEPLOYMENT_NOTIFICATIONS_CHANNEL}",
            color: 'good',
            iconEmoji: ':tada:',
            username: 'Deploy',
            message: "successfully finished deployment for ${env.JOB_NAME} <${env.BUILD_URL}|Open>"
        }
        unsuccessful {
          slackSend channel: "${env.DEPLOYMENT_NOTIFICATIONS_CHANNEL}",
            color: 'danger',
            iconEmoji: ':warning:',
            username: 'Deploy',
            message: "deploy failed for ${env.JOB_NAME} <${env.BUILD_URL}|Open>"
        }
      }
    } /* end: stage */
  } /* end: stages */
  post {
    always {
      sh "sudo chown \$(whoami):\$(whoami) -R ${env.WORKSPACE}"
    }
  }
} /* end: pipeline */
