/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.lucene.gradle.plugins.gitinfo.GitInfoExtension

import java.nio.charset.StandardCharsets
import java.nio.file.Files
import org.apache.lucene.gradle.plugins.misc.QuietExec

plugins {
  id 'signing'
}

// This project puts together the Lucene "distribution", assembling bits and pieces
// from across the project structure into release artifacts.

Provider<Boolean> signOption = buildOptions.addBooleanOption("sign", "Sign assembled distribution artifacts.", false)

ext {
  releaseDir = file("${buildDir}/release")
  withSignedArtifacts = signOption.get()
}

// Collect git revision.
GitInfoExtension gitInfoExt = rootProject.extensions.getByName("gitinfo")
MapProperty<String, String> gitStatus = gitInfoExt.getGitInfo()
Provider<String> gitRev = gitStatus.getting("git.commit")

// Prepare the "source" distribution artifact. We use raw git export, no additional complexity needed.
Provider<RegularFile> sourceTgzFile = project.layout.buildDirectory.file("packages/lucene-${version}-src.tgz")
tasks.register("assembleSourceTgz", QuietExec, {
  description = "Assemble source Lucene artifact as a .tgz file."

  inputs.property("git-revision", gitRev)
  outputs.file sourceTgzFile

  executable = buildGlobals.externalTool("git")
  workingDir = project.rootDir

  // An explicit GIT_DIR to prevent .git upward scanning if something goes wrong.
  if (gitInfoExt.getDotGitDir().isPresent()) {
    environment("GIT_DIR", gitInfoExt.getDotGitDir().get().asFile.toString())
  } else {
    doFirst {
      throw new GradleException("Can't assemble source tgz without a full git clone.")
    }
  }

  args += [
    "archive",
    "--format",
    "tgz",
    "--prefix",
    "lucene-${version}/",
    "--output",
    sourceTgzFile.get().asFile,
    "HEAD"
  ]
})


// Prepare the "binary" distribution artifact.
apply from: buildscript.sourceFile.toPath().resolveSibling("binary-release.gradle")

// Configure maven artifact collection to a local build folder (required to collect artifacts for the release).
apply from: buildscript.sourceFile.toPath().resolveSibling("collect-maven-artifacts.gradle")

// Configure release artifact signing.
tasks.register("signReleaseArchives", Sign, {
  dependsOn tasks.assembleBinaryTgz
  sign tasks.assembleBinaryTgz

  // The source tgz is not an archive task so be explicit about the outputs to sign.
  dependsOn tasks.assembleSourceTgz
  sign sourceTgzFile.get().asFile
})


// Set up the HTML-rendered "changes" distribution artifact by linking to documentation's output.
configurations {
  changesHtml
}

dependencies {
  changesHtml project(path: ":lucene:documentation", configuration: "changesHtml")
}


// Compute checksums for release archives.
tasks.register("computeChecksums", org.apache.lucene.gradle.Checksum, {
  files = objects.fileCollection()
  [
    tasks.assembleSourceTgz,
    tasks.assembleBinaryTgz,
  ].each { dep ->
    dependsOn dep
    files += dep.outputs.files
  }

  outputDir = file("${buildDir}/checksums")
})


tasks.register("prepareGitRev", {
  Provider<RegularFile> outputFile = project.layout.buildDirectory.file(".gitrev")

  inputs.property("gitrev", gitRev)
  outputs.file(outputFile)

  doFirst {
    Files.writeString(outputFile.get().asFile.toPath(), gitRev.get(), StandardCharsets.UTF_8)
  }
})


// Assemble everything needed in the release folder structure.
tasks.register("assembleRelease", Sync, {
  description = "Assemble all Lucene artifacts for a release."

  from(configurations.changesHtml, {
    into "changes"
  })

  from(tasks.mavenToBuild, {
    into "maven"
  })

  from tasks.prepareGitRev
  from tasks.assembleSourceTgz
  from tasks.assembleBinaryTgz

  from tasks.computeChecksums

  // Conditionally, attach signatures of all the release archives.
  if (project.ext.withSignedArtifacts) {
    from tasks.signReleaseArchives
  }

  into releaseDir
})


// Add the description and task group to some of the tasks that make
// sense at the user-level help.
tasks.matching {
  it.name in [
    "assembleSourceTgz",
    "assembleBinaryTgz",
    "assembleRelease",
  ]
}.configureEach {
  group = "distribution"
}
