// 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 {
  dependencies {
    // Excluding bouncycastle due to:
    // https://github.com/apache/hadoop/blob/4d7825309348956336b8f06a08322b78422849b1/hadoop-client-modules/hadoop-client-runtime/pom.xml#L156-L157
    exclude dependency("org.bouncycastle::.*")
  }
  // TODO(achennaka): Figure out a better way to deal with MR-JAR specific files. For now
  // we exclude everything as there were no failures seen but probably we need to exclude
  // based on the target release version.
  exclude "META-INF/versions/9/**"
  exclude "META-INF/versions/1?/**"
  // Current Gradle version(7.6.4) used to compile Java projects of Kudu project doesn't support
  // anything above Java19.
  // https://docs.gradle.org/current/userguide/compatibility.html#java_runtime
  exclude "META-INF/versions/2?/"
  relocate "com.google.common", "org.apache.kudu.shaded.com.google.common"
  relocate "com.google.flatbuffers", "org.apache.kudu.shaded.com.google.flatbuffers"
  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.compileOnly.extendsFrom(configurations.compileUnshaded)

// We use afterEvaluate to add additional configuration once all the definitions
// in the projects build script have been applied
afterEvaluate {
  // 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))
      }
    }
  }
}

