#!groovy

// 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 'UKNOWN' }
}

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"
  }
  try {
    node {
      def rootPath = "/src/rancher-validation/"
      def job_name = "${JOB_NAME}"
      if (job_name.contains('/')) { 
        job_names = job_name.split('/')
        job_name = job_names[job_names.size() - 1] 
      }
      
      def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup"
      def testContainer = "${job_name}${env.BUILD_NUMBER}_test"

      def deployPytestOptions = "-k test_deploy_rancher_server"

      def setupResultsOut = "setup-results.xml"
      def testResultsOut = "results.xml"
      def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}"
      def testsDir = "tests/v3_api/"

      def envFile = ".env"
      def rancherConfig = "rancher_env.config"

      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
                      ])
          }

          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"
            }
            try {
              stage('Run Validation Tests') {
                try {
                  // deploy rancher server
                  sh "docker run --name ${setupContainer} -t --env-file ${envFile} " +
                    "${imageName} /bin/bash -c \'export RANCHER_SERVER_VERSION=${rancher_version} && " +
                    "pytest -v -s --junit-xml=${setupResultsOut} " +
                    "${deployPytestOptions} ${testsDir}\'"

                  // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN and load into environment variables
                  sh "docker cp ${setupContainer}:${rootPath}${testsDir}${rancherConfig} ."
                  load rancherConfig

                  // run tests
                  sh "docker run --name ${testContainer} -t --env-file ${envFile} " +
                    "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} " +
                    "&& export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} " +
                    "&& pytest -v -s --junit-xml=${testResultsOut} " +
                    "${PYTEST_OPTIONS} ${testsDir}\'"
                } catch(err) {
                  echo "Error: " + err
                  echo 'Test run had failures. Collecting results...'
                }
              }

              stage('Test Report') {
                // copy and archive test results
                sh "docker cp ${setupContainer}:${rootPath}${setupResultsOut} ."
                sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ."

                step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut}"])
                step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"])

                sh "docker rm -v ${setupContainer}"
                sh "docker rm -v ${testContainer}"
                sh "docker rmi ${imageName}"
              }
            } catch(err){
              sh "docker stop ${setupContainer}"
              sh "docker stop ${testContainer}"

              sh "docker rm -v ${setupContainer}"
              sh "docker rm -v ${testContainer}"

              sh "docker rmi ${imageName}"
            }
          }
        }
      }
    }
  } catch(err) {
    echo "Error: " + err
    error()
  }
}