// 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 file contains tasks and configuration to support shading dependencies
// consistently when a subproject requires shaded artifacts.

import org.gradle.api.internal.artifacts.publish.ArchivePublishArtifact

apply plugin: "com.github.johnrengelman.shadow"

knows.enabled = false // Disable the "easter egg" knows task.
knows.group = "" // Hide the "easter egg" knows task.
shadowJar.group = "" // Hide shadowJar task since it's used by the default build.

// Add a property to explicitly allow slf4j shading.
ext {
  shadowIncludeSlf4j = false
}

// Configure a shaded jar to replace the default jar
shadowJar.classifier = null // Configure shadow jar to have the default classifier.
jar.finalizedBy(shadowJar)  // Generate the shaded jar anytime the jar task is run.
jar.classifier = "unshaded" // Add an unshaded classifier to the default jar.

// Add the shadowJar to the published artifacts.
artifacts {
  archives shadowJar
}

// Remove the unshaded jar from the published artifacts.
configurations.archives.artifacts.removeAll {
  it instanceof ArchivePublishArtifact && it.archiveTask == jar
}

// Ensure we always relocate these shaded dependencies to the same
// location across all modules.
shadowJar {
  relocate "com.google.common", "org.apache.kudu.shaded.com.google.common"
  relocate "com.google.gradle.osdetector", "org.apache.kudu.shaded.com.google.gradle.osdetector"
  relocate "com.google.gson", "org.apache.kudu.shaded.com.google.gson"
  relocate "com.google.protobuf", "org.apache.kudu.shaded.com.google.protobuf"
  relocate "com.google.thirdparty", "org.apache.kudu.shaded.com.google.thirdparty"
  relocate "com.sangupta", "org.apache.kudu.shaded.com.sangupta"
  // Pulled in via osdetector.
  relocate "kr.motd.maven", "org.apache.kudu.shaded.kr.motd.maven"
  relocate "org.apache.http", "org.apache.kudu.shaded.org.apache.http"
  relocate "org.apache.commons", "org.apache.kudu.shaded.org.apache.commons"
  // Pulled in via Guava.
  relocate "org.checkerframework", "org.apache.kudu.shaded.org.checkerframework"
  relocate "org.hamcrest", "org.apache.kudu.shaded.org.hamcrest"
  relocate "org.HdrHistogram", "org.apache.kudu.shaded.org.HdrHistogram"
  // Pulled in via Micrometer.
  relocate "org.LatencyUtils", "org.apache.kudu.shaded.org.LatencyUtils"
  relocate "io.micrometer", "org.apache.kudu.shaded.io.micrometer"
  relocate "io.netty", "org.apache.kudu.shaded.io.netty"
  relocate "scopt", "org.apache.kudu.shaded.scopt"
}

// ------------------------------------------------------------------
// Everything below is a "hack" to support partial shading and
// accurate pom generation. At some point this logic should exist
// in the shadow plugin itself.
// https://github.com/johnrengelman/shadow/issues/166
// https://github.com/johnrengelman/shadow/issues/159
// ------------------------------------------------------------------

// Add a configuration to support unshaded compile dependencies.
// By default shadow assumes all dependencies are shaded.
configurations.create("compileUnshaded")
configurations.shadow.extendsFrom(configurations.compileUnshaded)
configurations.compile.extendsFrom(configurations.compileUnshaded)

// We use afterEvaluate to add additional configuration once all the definitions
// in the projects build script have been applied
afterEvaluate {
  // Ensure compileUnshaded dependencies are included in the pom.
  [install, uploadArchives].each { task ->
    task.repositories.each {
      configure(it.pom.scopeMappings) {
        // The priority value is arbitrary.
        addMapping(
            MavenPlugin.COMPILE_PRIORITY,
            configurations.compileUnshaded,
            Conf2ScopeMappingContainer.COMPILE)
      }
    }
  }

  // Ensure we never shade SLF4J unless we explicitly specify it.
  // This is a workaround because in the shadow plugin exclusions from
  // parent modules are not respected in modules that use them.
  if (!shadowIncludeSlf4j) {
    shadowJar {
      dependencies {
        exclude(dependency("org.slf4j:slf4j-api:.*"))
      }
    }
  }

  // Ensure compileUnshaded dependencies are not compiled into shadowJar.
  project.configurations.compileUnshaded.dependencies.each { dep ->
    def depStr = "${dep.group}:${dep.name}:${dep.version}"
    logger.info "Excluding ${depStr} from being bundled into the shaded jar."
    shadowJar {
      dependencies {
        exclude(dependency(depStr))
      }
    }
  }
}

// Remove the shaded dependencies from the generated pom.
// This hack allows the project to support partially shaded jars,
// where the shadow plugin by default would remove all compile and runtime dependencies.
tasks.withType(Upload) {
  def installer = install.repositories.mavenInstaller
  def deployer = uploadArchives.repositories.mavenDeployer

  // Handle install and deploy in the same way.
  [installer, deployer]*.pom*.whenConfigured { pom ->
    def filter = shadowJar.getDependencyFilter()
    def configs = shadowJar.getConfigurations()

    def shadowDependencies = configs.collectMany {
      // Find all dependencies included in the shaded jar.
      it.resolvedConfiguration.firstLevelModuleDependencies.findAll {
        filter.isIncluded(it)
      }
    }

    // Remove the shaded dependencies from the pom.
    shadowDependencies.each { shaded ->
      def depStr = "${shaded.getModuleGroup()}:${shaded.getModuleName()}:${shaded.getModuleVersion()}"
      logger.info "Excluding ${depStr} from the generated pom."
      pom.dependencies.removeAll { dep ->
        dep.groupId == shaded.getModuleGroup() &&
        dep.artifactId == shaded.getModuleName() &&
        dep.version == shaded.getModuleVersion()
      }
    }

    // Re-sort the generated maven dependencies to make pom comparisons easier.
    pom.dependencies = pom.dependencies.sort { dep ->
      "$dep.scope:$dep.optional:$dep.groupId:$dep.artifactId"
    }
  }
}