import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.github.jk1.license.filter.LicenseBundleNormalizer
import com.github.jk1.license.render.InventoryMarkdownReportRenderer

plugins {
  id "com.github.johnrengelman.shadow"
  id "com.github.jk1.dependency-license-report" version "1.16"
}

description = 'OpenTelemetry Javaagent'

group = 'io.opentelemetry.javaagent'

apply from: "$rootDir/gradle/java.gradle"
apply from: "$rootDir/gradle/publish.gradle"

configurations {
  shadowInclude
}

processResources {
  from(rootProject.file("licenses")) {
    into("META-INF/licenses")
  }
}

jar {
  manifest {
    attributes(
      "Main-Class": "io.opentelemetry.javaagent.OpenTelemetryAgent",
      "Agent-Class": "io.opentelemetry.javaagent.OpenTelemetryAgent",
      "Premain-Class": "io.opentelemetry.javaagent.OpenTelemetryAgent",
      "Can-Redefine-Classes": true,
      "Can-Retransform-Classes": true,
    )
  }
}

CopySpec isolateSpec(Collection<Project> projectsWithShadowJar) {
  return copySpec {
    from({ projectsWithShadowJar.tasks.shadowJar.collect { zipTree(it.archiveFile) } }) {
      // important to keep prefix 'inst' short, as it is prefixed to lots of strings in runtime mem
      into 'inst'
      rename '(^.*)\\.class$', '$1.classdata'
      // Rename LICENSE file since it clashes with license dir on non-case sensitive FSs (i.e. Mac)
      rename '^LICENSE$', 'LICENSE.renamed'
    }
  }
}

//Includes everything needed for OOTB experience
shadowJar {
  dependsOn ':instrumentation:shadowJar'
  def projectsWithShadowJar = [project(':instrumentation')]
  with isolateSpec(projectsWithShadowJar)
}

//Includes instrumentations, but not exporters
task lightShadow(type: ShadowJar) {
  from sourceSets.main.output

  dependsOn ':instrumentation:shadowJar'
  def projectsWithShadowJar = [project(':instrumentation')]
  with isolateSpec(projectsWithShadowJar)
}

publishing {
  publications {
    maven(MavenPublication) {
      artifact lightShadow
    }
  }
}

tasks.withType(ShadowJar).configureEach {
  configurations = [project.configurations.shadowInclude]
  mergeServiceFiles()

  manifest {
    inheritFrom project.tasks.jar.manifest
  }

  exclude '**/module-info.class'

  // Prevents conflict with other SLF4J instances. Important for premain.
  relocate 'org.slf4j', 'io.opentelemetry.javaagent.slf4j'
  // rewrite dependencies calling Logger.getLogger
  relocate 'java.util.logging.Logger', 'io.opentelemetry.javaagent.bootstrap.PatchLogger'

  // prevents conflict with library instrumentation
  relocate 'io.opentelemetry.instrumentation.api', 'io.opentelemetry.javaagent.shaded.instrumentation.api'

  // relocate OpenTelemetry API
  relocate "io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api"
  relocate "io.opentelemetry.semconv", "io.opentelemetry.javaagent.shaded.io.opentelemetry.semconv"
  relocate "io.opentelemetry.spi", "io.opentelemetry.javaagent.shaded.io.opentelemetry.spi"
  relocate "io.opentelemetry.context", "io.opentelemetry.javaagent.shaded.io.opentelemetry.context"

  // relocate the OpenTelemetry extensions that are used by instrumentation modules
  // these extensions live in the AgentClassLoader, and are injected into the user's class loader
  // by the instrumentation modules that use them
  relocate "io.opentelemetry.extension.aws", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.aws"
  relocate "io.opentelemetry.extension.kotlin", "io.opentelemetry.javaagent.shaded.io.opentelemetry.extension.kotlin"
}

configurations {
  licenseReportDependencies
}

dependencies {
  testCompileOnly project(':javaagent-bootstrap')
  testCompileOnly project(':javaagent-api')

  testImplementation deps.guava

  testImplementation 'io.opentracing.contrib.dropwizard:dropwizard-opentracing:0.2.2'

  shadowInclude project(path: ':javaagent-bootstrap')

  // TODO ideally this would be :instrumentation instead of :javaagent-tooling
  //  in case there are dependencies (accidentally) pulled in by instrumentation modules
  //  but I couldn't get that to work
  licenseReportDependencies project(':javaagent-tooling')
  licenseReportDependencies project(':javaagent-bootstrap')
}

tasks.withType(Test).configureEach {
  jvmArgs "-Dotel.javaagent.debug=true"

  doFirst {
    // Defining here to allow jacoco to be first on the command line.
    jvmArgs "-javaagent:${shadowJar.archivePath}"
  }

  testLogging {
    events "started"
  }

  dependsOn shadowJar
}
assemble.dependsOn lightShadow
assemble.dependsOn shadowJar

licenseReport {
  outputDir = rootProject.file("licenses")

  renderers = [new InventoryMarkdownReportRenderer()]

  configurations = ["licenseReportDependencies"]

  excludeGroups = [
    "io.opentelemetry.instrumentation",
    "io.opentelemetry.javaagent"
  ]

  filters = [new LicenseBundleNormalizer(bundlePath: "$projectDir/license-normalizer-bundle.json")]
}

def cleanLicenses = tasks.register("cleanLicenses", Delete) {
  delete(rootProject.file("licenses"))
}

tasks.named("generateLicenseReport").configure {
  dependsOn(cleanLicenses)
}
