@Library('infraLib') _

def get30FromBuildLog(){
  def logs = currentBuild.rawBuild.getLog(30).join('\n')
  return "${logs}"
}
def getCronString(){
 switch (env.BRANCH_NAME) {
   case 'master':
     return 'H 3 * * *'
     break
   case 'develop':
     return 'H 4 * * 1,2,3,4,5'
     break
   default:
     return ''
     break
  }
}

String cron_string   = getCronString()
String[] URI_METRICS = "throughput concurrency succ fail avg_rt stdev_rt avg_lt avg_ct bytes".split()

pipeline {
  agent {
    label 'linux-agents'
  }

  triggers {
    cron(cron_string)
  }

  environment {
    AWS_PROFILE    = 'gdb-infra-dev'
    AWS_ACCOUNT_ID = '483193324480'
    AWS_REGION     = 'us-east-1'

    ECR_REGISTRY        = "${env.AWS_ACCOUNT_ID}.dkr.ecr.${env.AWS_REGION}.amazonaws.com"
    ECR_REPOSITORY_NAME = "infra/locust-runner"
    ECR_REGISTRY_URI    = "${env.ECR_REGISTRY}/${ECR_REPOSITORY_NAME}"

    PERFORMANCE_TEST_CLIENT_ID     = '1L0oorfhvpP6DFSN7LmNryy68jeI2t8D'
    PERFORMANCE_TEST_CLIENT_SECRET = utility.getSecretValueById('infra/jenkins/rti/common/PERFORMANCE_TEST_CLIENT_SECRET', env.AWS_PROFILE)
    AUTH0_AUDIENCE                 = 'https://dev-api.sma.stream'
    AUTH0_ISSUER                   = 'https://sme-dna.auth0.com'
    TARGET_URL                     = 'https://dev-api.insights.stream'
    DD_CLIENT_API_KEY              = utility.getSecretValueById('infra/jenkins/rti/common/DD_CLIENT_API_KEY', env.AWS_PROFILE)
    NOTIFICATIONS_CHANNEL          = '#rti-test-reports'
    REPORT_XML_FILE                = 'aggregate-results.xml'
    DD_DASHBOARD_LINK              = 'https://app.datadoghq.com/dashboard/ibi-aam-q6f/apollo-performance-load-testing'
  }

  options {
    timeout(time: 180, unit: 'MINUTES')
    buildDiscarder logRotator(
      artifactDaysToKeepStr: '',
      artifactNumToKeepStr: '',
      daysToKeepStr: '',
      numToKeepStr: '30'
    )
    disableResume()
    disableConcurrentBuilds()
    ansiColor('xterm')
  }

  stages {
    stage('Build') {
      steps {
        sh label: 'docker login', script: """
          aws ecr get-login --no-include-email --region us-east-1 \
          | awk '{print \$6}' \
          | docker login -u AWS --password-stdin https://${ECR_REGISTRY} \
          || aws ecr get-login-password --region us-east-1 \
          | docker login -u AWS --password-stdin https://${ECR_REGISTRY}
        """
        sh label: 'docker build', script: """
          docker build \
            --cache-from ${env.ECR_REGISTRY_URI}:latest \
            -t ${env.ECR_REGISTRY_URI}:latest .
        """
      }
    }
    stage('Push') {
      steps {
        sh label: 'docker login', script: """
          aws ecr get-login --no-include-email --region us-east-1 \
          | awk '{print \$6}' \
          | docker login -u AWS --password-stdin https://${ECR_REGISTRY} \
          || aws ecr get-login-password --region us-east-1 \
          | docker login -u AWS --password-stdin https://${ECR_REGISTRY}
        """
        sh label: 'docker build', script: """
          docker push ${env.ECR_REGISTRY_URI}:latest
        """
      }
    }
    stage('Test') {
      steps {
        script {
          docker.image("${env.ECR_REGISTRY_URI}:latest").inside {
            sh label: 'replace target URL', script: '''
              envsubst < bztfile.yml.tmpl > bztfile.yml
            '''
            bzt '-report bztfile.yml'
          }
          if (fileExists(env.REPORT_XML_FILE) && ( env.BRANCH_NAME == "master" || env.BRANCH_NAME == "develop" )) {
            dd_timestamp = sh(returnStdout: true, script: "date +%s").trim()
            xml = readFile(env.REPORT_XML_FILE)
            labels = utility.getBztReportGroupLabels(xml)
            for (label in labels) {
              for (metric_name in URI_METRICS){
                metric_val=utility.getBztReportGroupMetricValue(xml,label,metric_name)
                ddResponse=utility.dataDogMetricPut(
                  "artistapp_load_test.all_test.${metric_name}",
                  "${metric_val}",
                  "${dd_timestamp}",
                  "${env.DD_CLIENT_API_KEY}",
                  "${label.replace('-', '_').replace(' ', '_')}",
                  "[ \"environment:Jenkins\", \"branch:${env.BRANCH_NAME}\", \"metric_name:${metric_name}\", \"label:${label.replace('-', '_').replace(' ', '_')}\", \"BASE_URI:${env.TARGET_URL}\" ]"
                )
                println 'LABEL: '+label.replace('-', '_').replace(' ', '_') +' metric: ' + metric_name + ' val: '+ metric_val +' DD:'+ddResponse
              }
            }
          }
        }
      }
    }
  }
  post {
    success {
      script {
        external_report_link = utility.getBztReportURL(readFile(env.REPORT_XML_FILE))
        utility.slackNotifyMainBranches(
          "SUCCESS",
          env.NOTIFICATIONS_CHANNEL,
          "Performance test done, please see results <${external_report_link}|Last Build Report> and <${env.BUILD_URL}/performance/|Last Build Performance Trend>, <${env.DD_DASHBOARD_LINK}|DataDog Dashboard>"
        )
      }
    }
    unstable {
      script {
        errorLog = get30FromBuildLog()
        external_report_link = utility.getBztReportURL(readFile(env.REPORT_XML_FILE))
        println "ReportLink:" +external_report_link
        slackResponse = utility.slackNotifyMainBranches(
          "UNSTABLE",
          env.NOTIFICATIONS_CHANNEL,
          "Performance test is unstable, please see results <${external_report_link}|Last Build Report> and  <${env.BUILD_URL}/performance/|Last Build Performance Trend>. Most likely pass/fail criteria triggered this build UNSTABLE"
        )
        if (!slackResponse.toString().isInteger()) {
          blocks = [
            [
              "type": "section",
              "text": [
                "type": "mrkdwn",
                "text": "```${errorLog}```"
              ]
            ]
          ]
          slackSend(channel: slackResponse.threadId,
                    iconEmoji: ":hammer_and_wrench:",
                    blocks: blocks)
        }
      }
    }
    aborted {
      script {
        external_report_link = utility.getBztReportURL(readFile(REPORT_XML_FILE))
        utility.slackNotifyMainBranches(
          "ABORTED",
          env.NOTIFICATIONS_CHANNEL,
          "Performance test ABORTED, <${env.BUILD_URL}|Please delete aborted build> to keep statistic clean"
        )
      }
    }
    failure {
      script {
        errorLog = get30FromBuildLog()
        slackResponse = utility.slackNotifyMainBranches(
          "FAILURE",
          env.NOTIFICATIONS_CHANNEL,
          "Performance test FAIL, <${env.BUILD_URL}|Please fix it> and delete failed build to keep statistic clean."
        )
        if (!slackResponse.toString().isInteger()) {
          blocks = [
            [
              "type": "section",
              "text": [
                "type": "mrkdwn",
                "text": "```${errorLog}```"
              ]
            ]
          ]
          slackSend(channel: slackResponse.threadId,
                    iconEmoji: ":hammer_and_wrench:",
                    blocks: blocks)
        }
      }
    }
  }
}
