// 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.

import build.bazel.ci.JenkinsUtils
import build.bazel.ci.BazelConfiguration

private def ensureGpgSecretKeyImported() {
  sh '''#!/bin/bash
echo "Import GPG Secret key"
(gpg --list-secret-keys | grep "${APT_GPG_KEY_ID}" > /dev/null) || \\
  gpg --allow-secret-key-import --import "${APT_GPG_KEY_PATH}"
# Make sure we use stronger digest algorithm.
# We use reprepro to generate the debian repository,
# but there is no way to pass flags to gpg using reprepro, so writting it into
# ~/.gnupg/gpg.conf
(grep "digest-algo sha256" ~/.gnupg/gpg.conf > /dev/null) || \\
  echo "digest-algo sha256" >> ~/.gnupg/gpg.conf
'''
}

// Generate the SHA-256 checksum and the GPG signature for a list of artifacts.
// Returns a new list of artifacts that include the generated checksum and signature files.
private def signArtifacts(files) {
  def result = []
  def script = []
  for (def file : files) {
    script <<= "echo 'Signing ${file}'"
    script <<= "(cd \"\$(dirname '${file}')\" && sha256sum \"\$(basename '${file}')\") > '${file}.sha256'"
    script <<= "gpg --no-tty --detach-sign -u \"\${APT_GPG_KEY_ID}\" '${file}'"
    result <<= file
    result <<= "${file}.sha256"
    result <<= "${file}.sig"
  }
  sh "#!/bin/bash \n${script.join '\n'}"
  return result
}

@NonCPS
private def listArtifacts(ws, dir, excludes) {
  return JenkinsUtils.list(env, "${ws}/${dir}", excludes).collect { "${dir}/${it}" }
}

private def listStashes(configuration, restrict_configuration) {
  def result = []
  def conf = BazelConfiguration.flattenConfigurations(
    BazelConfiguration.parse(configuration), restrict_configuration)
  for (k in conf.keySet()) {
    if ("stash" in conf[k] || "archive" in conf[k]) {
      result.add("bazel--node=${k.node}--variation=${k.variation}")
    }
  }
  return result
}

// A step that push a release for Bazel.
def call(params = [:]) {
  // Parameters
  def r_name = params.name
  def bucket = params.get("bucket", "bazel")
  def release_script = params.get("release_script", "source scripts/ci/build.sh; deploy_release")
  def email_script = params.get("email_script", "source scripts/ci/build.sh; generate_email")
  def repository = params.get("repository", "https://github.com/bazelbuild/bazel")
  def replyTo = params.get("replyTo", "bazel-ci@googlegroups.com")

  def ws = pwd()

  // Save the build log
  JenkinsUtils.saveLog(env, currentBuild, "${ws}/build.log")

  // unstash all the things
  dir("artifacts") {
    def stashNames = listStashes(params.configuration, params.restrict_configuration)
    for (def stashName : stashNames) {
      unstash stashName
    }
  }
  def artifacts = listArtifacts(ws, "artifacts", params.get("excludes", []))

  // Now the actual release
  withEnv(["GCS_BUCKET=${bucket}",
           "GIT_REPOSITORY_URL=${repository}",
           "GITHUB_TOKEN=${readFile(env.GITHUB_TOKEN_FILE).trim()}",
           "APT_GPG_KEY_ID=${readFile(env.APT_GPG_KEY_ID_FILE).trim()}",
           // TODO(dmarting): hack to work with release_to_apt(), we should get rid of it.
           "tmpdir=${ws}/artifacts/node=linux-x86_64/variation="]) {
    // Sign artifacts
    ensureGpgSecretKeyImported()
    def artifact_list = signArtifacts(artifacts)

    // Release
    sh "#!/bin/bash\n${release_script} build.log ${artifact_list.join ' '}"

    // Send email announcement
    stage("Announcement mail") {
      def email = sh(script: "bash -c '${email_script}'", returnStdout: true)
      echo "Mail to: ${email}"
      if (r_name.contains("test")) {
        echo "Test release, skipping announcement mail."
      } else {
        def splittedEmail = email.split("\n", 3)
        mail(subject: splittedEmail[1],
             to: splittedEmail[0],
             replyTo: replyTo,
             body: splittedEmail[2])
      }
    }
  }
}
