@Library('test-shared-library') _

final String MODE_PR = 'MODE_PR'
final String MODE_MASTER = 'MODE_MASTER'
final String DEFAULT_NODE_LABEL = 'h2o-3'
final int HEALTH_CHECK_RETRIES = 5

def defineTestStages = null
def pipelineContext = null
String result = 'FAILURE'
def scmEnv = null

final boolean prJob = env.CHANGE_BRANCH || env.ghprbPullId
def mode = null

try {
  ansiColor('xterm') {
    timestamps {

      if (prJob) {
        echo "********* USING PR PIPELINE CONFIGURATION *********"
        if (!env.ghprbPullId) {
          // cancel previous builds only for regular PRs, don't cancel for external PRs
          cancelPreviousBuilds()
        }
        mode = MODE_PR
      } else {
        echo "********* USING MASTER PIPELINE CONFIGURATION *********"
        mode = MODE_MASTER
      }

      boolean healthCheckPassed = false
      int attempt = 0
      stage('Checkout and Build') {
        while (!healthCheckPassed) {
          attempt += 1
          if (attempt > HEALTH_CHECK_RETRIES) {
            error "Too many attempts to pass initial health check"
          }
          String nodeLabel = DEFAULT_NODE_LABEL
          if (pipelineContext != null) {
            nodeLabel = "h2o-3"
          }
          echo "######### NodeLabel: ${nodeLabel} #########"
          node(nodeLabel) {
            dir('h2o-3') {
              // clear the folder
              deleteDir()
              // checkout H2O-3
              retryWithTimeout(180, 3) {
                echo "###### Checkout H2O-3 ######"
                if (env.ghprbPullId) {
                  // building PR from fork
                  sh """
                    git init
                    git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
                    git config remote.origin.url https://github.com/h2oai/h2o-3
                    git config --add safe.directory .


                    git fetch --no-tags origin pull/${env.ghprbPullId}/head:remote-${env.ghprbSourceBranch}
                    git checkout ${env.ghprbActualCommit}
                    git checkout -b ${env.ghprbSourceBranch}
                  """
                  scmEnv = [
                    GIT_BRANCH: env.ghprbSourceBranch,
                    GIT_TARGET: env.ghprbTargetBranch,
                    GIT_COMMIT: env.ghprbActualCommit,
                    GIT_URL: 'https://github.com/h2oai/h2o-3'
                  ]
                  env.BUILDING_FORK = true
                } else {
                  // building regular PR
                  def prScmEnv = checkout scm
                  scmEnv = [
                    GIT_TARGET: env.CHANGE_TARGET
                  ] + prScmEnv
                }
              }
            }
            echo "$scmEnv"

            if (pipelineContext == null) {
              def initPipelineContext = load('h2o-3/scripts/jenkins/groovy/initPipelineContext.groovy')
              pipelineContext = initPipelineContext(scmEnv, mode, !prJob)
              pipelineContext.getBuildConfig().setJobProperties(this)
              // Load the defineTestStages script
              defineTestStages = load('h2o-3/scripts/jenkins/groovy/defineTestStages.groovy')
            }
            healthCheckPassed = pipelineContext.getHealthChecker().checkHealth(this, env.NODE_NAME, pipelineContext.getBuildConfig().getDefaultImage(), pipelineContext.getBuildConfig().DOCKER_REGISTRY, pipelineContext.getBuildConfig())
            if (healthCheckPassed) {
              // Load build script and execute it
              def buildH2O3 = load('h2o-3/scripts/jenkins/groovy/buildH2O3.groovy')
              buildH2O3(pipelineContext)
            }
          }
        }
      }

      defineTestStages(pipelineContext)
      result = 'SUCCESS'
    }
  }
} finally {
  if (pipelineContext != null) {
    if (!prJob) {
      pipelineContext.getEmailer().sendEmail(this, result, pipelineContext.getBuildSummary().getSummaryHTML(this))
    }
    if (!pipelineContext.getHealthChecker().getHealthProblems().isEmpty()) {
      pipelineContext.getEmailer().sendEmail(this, 'WARNING', pipelineContext.getHealthChecker().toEmail(this, pipelineContext), ['michalr@h2o.ai'])
    }
  }
}

def cancelPreviousBuilds() {
  echo "###### Cancelling all previous builds ######"
  def hi = Hudson.instance
  def jobNameParts = env.JOB_NAME.tokenize('/')
  def pname = jobNameParts[0]

  def item = hi.getItem(pname)
  // if called from multibranch pipeline/folder etc., we need to get the builds of the leaf item
  if (jobNameParts.size() > 1) {
    // remove the first element, because that has been already used to get the root item
    jobNameParts.remove(0)
    for (part in jobNameParts) {
      item = item.getItem(part)
    }
  }

  item.getBuilds().each{ build ->
    def exec = build.getExecutor()

    if (build.number < currentBuild.number && exec != null) {
      exec.doStop()
      println("Aborted previous running build #${build.number}")
    } else {
      println("Build is not running or is current build, not aborting - #${build.number}")
    }
  }
}
