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

package publishing

import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.plugins.JavaLibraryPlugin
import org.gradle.api.provider.Property
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.withType

@CacheableTask
abstract class GeneratePomProperties : DefaultTask() {
  @get:Input abstract val groupId: Property<String>

  @get:Input abstract val artifactId: Property<String>

  @get:Input abstract val projectVersion: Property<String>

  @get:OutputDirectory abstract val destinationDir: DirectoryProperty

  init {
    groupId.convention(project.provider { project.group.toString() })
    artifactId.convention(project.name)
    projectVersion.convention(project.provider { project.version.toString() })
    destinationDir.convention(project.layout.buildDirectory.dir("generated/pom-properties"))
  }

  @TaskAction
  fun generate() {
    val buildDir = destinationDir.get().asFile
    buildDir.deleteRecursively()
    val targetDir = buildDir.resolve("META-INF/maven/${groupId.get()}/${artifactId.get()}")
    targetDir.mkdirs()
    targetDir
      .resolve("pom.properties")
      .writeText(
        """
      # Generated by the Apache Polaris build.
      groupId=${groupId.get()}
      artifactId=${artifactId.get()}
      version=${projectVersion.get()}
    """
          .trimIndent()
      )
  }
}

/**
 * Adds convenient, but not strictly necessary information to each generated "main" jar.
 *
 * This includes `pom.properties` and `pom.xml` files where Maven places those, in
 * `META-INF/maven/group-id/artifact-id/`. Also adds the `NOTICE` and `LICENSE` files in `META-INF`,
 * which makes it easier for license scanners.
 */
fun addAdditionalJarContent(project: Project): Unit =
  project.run {
    project.plugins.withType(JavaLibraryPlugin::class.java) {
      val generatePomProperties =
        tasks.register("generatePomProperties", GeneratePomProperties::class.java) {}

      tasks.withType(Jar::class).configureEach {
        // Only add the pom.xml to jars for 'release' builds, but not for developer/snapshot builds.
        // Letting jars depend on the pom.xml (Gradle's `GenerateMavenPom` task, annotated with
        // `@UntrackedTask`)
        // breaks up-to-date checks for all jars and dependent project dependencies, leading to
        // unnecessarily long
        // build times.
        if (project.hasProperty("release")) {
          from(tasks.named<GenerateMavenPom>("generatePomFileForMavenPublication")) {
            include("pom-default.xml")
            eachFile { path = "META-INF/maven/${project.group}/${project.name}/pom.xml" }
          }
        }
        from(generatePomProperties) {
          include("**")
          eachFile { path = sourcePath }
        }
      }
    }
  }
