// 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,
                                   restrict_configuration: config.restrict_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 + conf.get("variation", ""),
                          extra_bazelrc: config.extra_bazelrc,
                          build_tag_filters: params.get("build_tag_filters", []),
                          test_tag_filters: params.get("test_tag_filters", []),
                          workspace: config.workspace
      )
    })
  }
  entrySet = null
  return cfgs
}

/**
 * This define a Jenkins step "bazelCiConfiguredJob" that use git and Bazel
 * with various configurations given by a list of platforms and a list of variation of Bazel.
 * 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
 *   - restrict_configuration: A map of acceptable descriptor values. If provided, for each key,
 *     only the values that are in that map will generate a configuration.
 *   - 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
 *   - 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["restrict_configuration"] = config.get("restrict_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["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"
    }
  }
}
