#!groovy

jobs = [:]
def job_name = "${JOB_NAME}"
if (job_name.contains('/')) { 
  job_names = job_name.split('/')
  job_name = job_names[job_names.size() - 1] 
}

def deleteContainer = "${job_name}${BUILD_NUMBER}_delete"
def deletePytestOptions = "-k test_delete_rancher_server"
def deleteResultsOut = "delete-results.xml"
def testsDir = "tests/v3_api/"
def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}"
def envFile = ".env"
def RANCHER_DEPLOYED = false

// RANCHER_VERSION resolution is first via Jenkins Build Parameter RANCHER_VERSION fed in from console,
// then from $DOCKER_TRIGGER_TAG which is sourced from the Docker Hub Jenkins plugin webhook.
def rancher_version() {
  try { if ('' != RANCHER_VERSION) { return RANCHER_VERSION } }
  catch (MissingPropertyException e) {}

  try { return DOCKER_TRIGGER_TAG }
  catch (MissingPropertyException e) {}

  echo  'Neither RANCHER_VERSION nor DOCKER_TRIGGER_TAG have been specified!'
  error()
}

def lastBuildResult() {
 def previous_build = currentBuild.getPreviousBuild()
  if ( null != previous_build ) { return previous_build.result } else { return 'UNKNOWN' }
}

def via_webhook() {
  try {
    def foo = DOCKER_TRIGGER_TAG
    return true
  } catch(MissingPropertyException) {
    return false
  }
}

// Filter out Docker Hub tags like 'latest', 'master', 'enterprise'.
// Just want things like v1.2*
def rancher_version = rancher_version()
def String rancher_version_regex = "^v[\\d]\\.[\\d]\\.[\\d][\\-rc\\d]+\$"

if ( true == via_webhook() && (!(rancher_version ==~ rancher_version_regex)) ) {
  println("Received RANCHER_VERSION \'${rancher_version}\' via webhook which does not match regex \'${rancher_version_regex}\'.")
  println("** This will **not** result in a pipeline run.")
  currentBuild.result = lastBuildResult()
} else {
  def branch = "v2.1"
  if (rancher_version.startsWith("v2.2") || rancher_version == "master" ) {
    branch = "master"
  }
  node {
    wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) {
      withFolderProperties {
        stage('Checkout') {
          deleteDir()
          checkout([
                    $class: 'GitSCM',
                    branches: [[name: "*/${branch}"]],
                    extensions: scm.extensions + [[$class: 'CleanCheckout']],
                    userRemoteConfigs: scm.userRemoteConfigs
                  ])
        }

        try {
          try {
            dir ("tests/validation") {
              stage('Configure and Build') {
                if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) {
                  dir(".ssh") {
                    def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64())
                    writeFile file: AWS_SSH_KEY_NAME, text: decoded
                  }
                }
                sh "./tests/v3_api/scripts/configure.sh"
                sh "./tests/v3_api/scripts/build.sh"
              }

              stage('Deploy Rancher server') {
                sh "docker run --name ${job_name}${BUILD_NUMBER} -t --env-file .env ${imageName} /bin/bash " +
                  "-c \'export RANCHER_SERVER_VERSION=${rancher_version} && pytest -v -s --junit-xml=setup.xml -k test_deploy_rancher_server tests/v3_api/\'"
                sh "docker cp ${job_name}${BUILD_NUMBER}:/src/rancher-validation/tests/v3_api/rancher_env.config ."
                load "rancher_env.config"
                RANCHER_DEPLOYED = true
              }
            } catch (err) {
                RANCHER_DEPLOYED = false
                echo "Error: " + err
                currentBuild.result = 'FAILURE'
                error()
            }

            stage('Run provisioning tests') {
              params = [ string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), string(name: 'BRANCH', value: branch) ]

              jobs["custom"] = { build job: 'rancher-v3_test_custom_cluster', parameters: params}
              jobs["do"] = { build job: 'rancher-v3_test_do_cluster', parameters: params }
              jobs["ec2"] = { build job: 'rancher-v3_test_ec2_cluster', parameters: params }
              jobs["az"] = { build job: 'rancher-v3_test_az_cluster', parameters: params }

              parallel jobs
            }
          } catch(err) {
            echo "Error: " + err
          } finally {
            stage('Delete Rancher Server') {
              try {
                if (RANCHER_DELETE_SERVER.toLowerCase() == "true" && RANCHER_DEPLOYED) {
                  echo "Sleeping for ${RANCHER_DELETE_DELAY} hours before deleting Rancher server"
                  sleep(time: RANCHER_DELETE_DELAY.toInteger(), unit: "HOURS")
                  sh "docker run --name ${deleteContainer} -t --env-file ${envFile} " +
                  "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " +
                  "export ADMIN_TOKEN=${ADMIN_TOKEN} && export USER_TOKEN=${USER_TOKEN} && "+
                  "pytest -v -s --junit-xml=${deleteResultsOut} " +
                  "${deletePytestOptions} ${testsDir}\'"
                }
                else {
                  echo "Rancher server not deployed, skipping delete."
                }
              } catch(err) {
                echo "Error: " + err
                currentBuild.result = 'FAILURE'
              }
            }

            stage('Test Report') {
              sh "docker cp ${job_name}${BUILD_NUMBER}:/src/rancher-validation/setup.xml ."
              step([$class: 'JUnitResultArchiver', testResults: '**/setup.xml'])
            }

            stage('Cleanup') {
              sh "docker stop ${job_name}${BUILD_NUMBER}"
              sh "docker rm -v ${job_name}${BUILD_NUMBER}"
              sh "docker rmi ${imageName}"
            }
          }
        }
      }
    }
  }
}