// Copyright (C) 2017 The Bazel Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

def createJobsFromConfiguration(config, configNames, script) {
  def cfgs = []
  def name = currentBuild.projectName
  // Convert to an array to avoid serialization issue with Jenkins
  def entrySet = readConfiguration(files: [".ci/${name}.json", "scripts/ci/${name}.json"],
                                   repository: config.repository,
                                   branch: config.branch,
                                   refspec: config.refspec,
                                   default_configuration: config.configuration
                                  ).entrySet().toArray()
  for (int k = 0; k < entrySet.length; k++) {
    def params = entrySet[k].value
    def conf = entrySet[k].key
    def configName = build.bazel.ci.BazelConfiguration.descriptorToString(conf)
    configNames.add(configName)
    cfgs.add({ ->
        script.bazelCiJob(name: configName,
                          repository: config.repository,
                          branch: config.branch,
                          refspec: config.refspec,
                          node_label: conf["node"],
                          targets: params.get("targets", ["//..."]),
                          tests: params.get("tests", ["//..."]),
                          configuration: params.get("configure", []),
                          build_opts: params.get("build_opts", []),
                          test_opts: params.get("test_opts", []),
                          startup_opts: params.get("startup_opts", []),
                          bazel_version: config.bazel_version,
                          extra_bazelrc: config.extra_bazelrc,
                          build_tag_filters: params.get("build_tag_filters", []),
                          test_tag_filters: params.get("test_tag_filters", []),
                          workspace: config.workspace,
                          sauce: config.sauce
      )
    })
  }
  entrySet = null
  return cfgs
}

/**
 * This define a Jenkins step "bazelCiConfiguredJob" that use git and Bazel
 * with various configurations given by a list of platforms.
 * Each arguments is set by a variable in the body of the step and the list of possible arguments
 * is:
 *   - bazel_version is the baseline for the version of Bazel, generally a parameter for the job.
 *        If set to 'custom', the job will try to fetch the Bazel binary from upstream.
 *   - configuration: JSON configuration, see BazelConfiguration
 *   - extra_bazelrc: extraneous content for the rc file, will go after all other options.
 *        Generally to be provided as a parameter of the job.
 *   - workspace: a directory, relative to the root of the repository, that contains
 *        the workspace file, default to the top directory.
 *   - repository: git repository to clone.
 *   - branch: branch of the repository to clone (default: master).
 *   - refspec: specification of the references to fetch
 *   - sauce: identifier of the crendentials to connect to SauceLabs.
 *   - run_sequentially: run each configuration sequentially rather than in parallel
 */
def call(config = [:]) {
  config["bazel_version"] = config.get("bazel_version", "latest")
  config["configuration"] = config.get("configuration", "[]")
  config["extra_bazelrc"] = config.get("extra_bazelrc", "")
  config["workspace"] = config.get("workspace", "")
  config["repository"] = config.get("repository", "")
  config["branch"] = config.get("branch", "master")
  config["refspec"] = config.get("refspec", "+refs/heads/*:refs/remotes/origin/*")
  config["sauce"] = config.get("sauce", "")
  config["run_sequentially"] = config.get("run_sequentially", false)

  // Remove special characters from bazel_version (which can be coming from a URL post):
  //   everything except [a-zA-Z0-9_-.]
  config.bazel_version = config.bazel_version.replaceAll("[^a-zA-Z0-9_\\.-]", "")

  def configs = [:]
  // Keep a list of keys of configs in configNames to workaround
  // https://issues.jenkins-ci.org/browse/JENKINS-27421
  def configNames = []
  stage("Setting-up configurations") {
    def cfgs = createJobsFromConfiguration(config, configNames, this)
    for (int i = 0; i < cfgs.size; i++) {
      configs[configNames[i]] = cfgs[i]
    }
    cfgs = null
  }


  timeout(240) {
    try {
      stage("Run configurations") {
        if (config.run_sequentially) {
          for (configName in configNames) {
            configs[configName]()
          }
        } else {
          parallel configs
        }
      }
    } catch(build.bazel.ci.BazelTestFailure ex) {
      // Do not mark the build as error with a test failure
      currentBuild.result = "UNSTABLE"
    }
  }
}
