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

/*
 * This script configures aspects related to all project publications,
 * this includes:
 *
 * - configuring maven artifacts,
 * - setting up target maven repositories for publications to end up on,
 * - configuring binary and source release artifacts,
 * - other concerns related to publishing artifacts (signing, checksums).
 */

if (project != project.rootProject) {
  throw new GradleException("Applicable to rootProject only: " + project.path)
}

//
// An explicit list of projects to publish as Maven artifacts.
//
def mavenProjects = project(":lucene").subprojects.findAll {subproject ->
  def excluded = [
    // Exclude distribution assembly, tests & documentation.
    ":lucene:distribution",
    ":lucene:documentation",
    // Exclude the parent container project for analysis modules (no artifacts).
    ":lucene:analysis",
    // Exclude the native module.
    ":lucene:misc:native",
    // Exclude test fixtures.
    ":lucene:spatial-test-fixtures",
    // Exclude JMH benchmarks.
    ":lucene:benchmarks-jmh",
  ]

  // Exclude all subprojects that are modular test projects and those explicitly
  // excluded above.
  return !(subproject.path.endsWith(".tests")
      || subproject.path.startsWith(":build-tools:")
      || subproject.path in excluded)
}

// Make projects available to other scripts. Perhaps we should think of another way to do it.
ext.set("mavenProjects", mavenProjects)


// Optionally, switch to using an external GPG command, using it's configured gpg-agent for key management
Provider<Boolean> useGpgOption = buildOptions.addBooleanOption("useGpg", "Use GPG for signing artifacts.", false)
if (useGpgOption.get()) {
  // Do this check before 'useGpgCmd()' (and once), otherwise gradle will fail with a confusing error about 'signatory.keyId'
  //
  // 'signatory.keyId' is an implementation detail of the SigningPlugin that it populates from 'signing.gnupg.keyName' when useGpgCmd()
  // is used -- but does not explain in the error produced if 'signing.gnupg.keyName' is not set.
  def propName = 'signing.gnupg.keyName'
  if (!project.hasProperty(propName)) {
    throw new GradleException("'$propName' project property must be set when using external GPG via 'useGpg', please see help/publishing.txt")
  }

  rootProject.allprojects {
    plugins.withType(SigningPlugin).configureEach {
      signing {
        useGpgCmd()
      }
    }
  }
}

configure(mavenProjects) { Project project ->
  project.apply plugin: 'maven-publish'
  project.apply plugin: 'signing'

  plugins.withType(JavaPlugin).configureEach {
    // We have two types of publications: jars and signed jars.
    publishing {
      publications {
        jars(MavenPublication)
        signedJars(MavenPublication)
      }
    }

    // signedJars publication is always signed.
    signing {
      sign publishing.publications.signedJars
    }

    // Each publication consists of the java components, source and javadoc artifacts.
    // Add tasks to assemble source and javadoc JARs.
    def sourcesJar = tasks.register("sourcesJar", Jar, {
      dependsOn "classes"
      archiveClassifier = 'sources'
      from sourceSets.main.allJava
    })

    def javadocJar = tasks.register("javadocJar", Jar, {
      dependsOn "javadoc"
      archiveClassifier = 'javadoc'
      from javadoc.destinationDir
    })

    publishing {
      publications.each { publication ->
        configure(publication) {
          from components.java
          groupId = project.group
          artifactId = project.base.archivesName.get()

          artifact sourcesJar
          artifact javadocJar
        }
      }
    }

    // Configure pom defaults for all publications.
    publishing {
      publications.each { publication ->
        configure(publication) {
          pom {
            name = provider { -> "Apache Lucene (module: ${project.name})" }
            description = provider { -> "Apache Lucene (module: ${project.name})" }
            url = "https://lucene.apache.org/"

            licenses {
              license {
                name = 'Apache 2'
                url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
              }
            }

            inceptionYear = "2000"

            issueManagement {
              system = "github"
              url = "https://github.com/apache/lucene/issues"
            }

            ciManagement {
              system = "Jenkins"
              url = "https://builds.apache.org/job/Lucene/"
            }

            mailingLists {
              mailingList {
                name = "Java User List"
                subscribe = "java-user-subscribe@lucene.apache.org"
                unsubscribe = "java-user-unsubscribe@lucene.apache.org"
                archive = "https://mail-archives.apache.org/mod_mbox/lucene-java-user/"
              }

              mailingList {
                name = "Java Developer List"
                subscribe = "dev-subscribe@lucene.apache.org"
                unsubscribe = "dev-unsubscribe@lucene.apache.org"
                archive = "https://mail-archives.apache.org/mod_mbox/lucene-dev/"
              }

              mailingList {
                name = "Java Commits List"
                subscribe = "commits-subscribe@lucene.apache.org"
                unsubscribe = "commits-unsubscribe@lucene.apache.org"
                archive = "https://mail-archives.apache.org/mod_mbox/lucene-java-commits/"
              }
            }

            scm {
              connection = 'scm:git:https://gitbox.apache.org/repos/asf/lucene.git'
              developerConnection = 'scm:git:https://gitbox.apache.org/repos/asf/lucene.git'
              url = 'https://gitbox.apache.org/repos/asf?p=lucene.git'
            }
          }
        }
      }
    }
  }

  // Hack: prevent any test fixture JARs from being published.
  afterEvaluate {
    configurations.matching { configuration ->
      configuration.name in [
        "testFixturesApiElements",
        "testFixturesRuntimeElements"
      ]
    }.configureEach {
      project.components.java.withVariantsFromConfiguration(it) { variant ->
        variant.skip()
      }
    }
  }

  // Hack: do not generate or publish gradle metadata files.
  tasks.withType(GenerateModuleMetadata).configureEach {
    enabled = false
  }
}

// Configure on-demand maven publishing into ~/.m2 for developers' convenience.
plugins.apply('lucene.publications.maven-to-local-m2')

// Configure ASF Nexus publications.
plugins.apply('lucene.publications.maven-to-nexus-releases')
plugins.apply('lucene.publications.maven-to-nexus-snapshots')
