/*
 * This file was generated by the Gradle 'init' task.
 * For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.7/userguide/building_java_projects.html in the Gradle documentation.
 */

plugins {
    // Apply the application plugin to add support for building a CLI application in Java.
    application

    // JMH Gradle Plugin
    // https://github.com/melix/jmh-gradle-plugin/blob/master/README.adoc#usage
    id("me.champeau.jmh") version "0.7.2"
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

val latestJmhVersion = "1.37"
val mockitoAgent = configurations.create("mockitoAgent")

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation(libs.junit.jupiter)
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")

    // Required to use the IntelliJ plugin "JMH Java Microbenchmark Harness".
    // https://stackoverflow.com/a/71286156/6334421
    jmhAnnotationProcessor("org.openjdk.jmh:jmh-generator-annprocess:$latestJmhVersion")

    // Use Mockito for mocking.
    // https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#mockito-instrumentation
    testImplementation(libs.mockito)
    mockitoAgent(libs.mockito) { isTransitive = false }
}

// Apply a specific Java toolchain to ease working on different environments.
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(23)
    }
}

// The `application` plugin provides the `JavaExec` task.
// It automatically creates one task of that type called `run`.
// It is not possible to rename it.
// Thus, we remove it and add two custom named `JavaExec` tasks instead.
tasks.getByName("run") {
    description = "This task has been disabled. It does nothing o.O"
    enabled = false
}

tasks.register<JavaExec>("runCbmCgl") {
    description = "Run Custom Benchmark (CBM) with Custom Generated Lists (CGL)"
    group = "application"
    classpath = sourceSets["main"].runtimeClasspath
    mainClass = "de.uni_marburg.powersort.benchmark.CbmCgl"
    // Results in `-Xmx4g` being passed to JVM
    maxHeapSize = "4g"
}
tasks.register<JavaExec>("runCbmCompetition") {
    description = "Run Custom Benchmark (CBM) with Powersort competition lists"
    group = "application"
    classpath = sourceSets["main"].runtimeClasspath
    mainClass = "de.uni_marburg.powersort.benchmark.CbmCompetition"
}

tasks {
    test {
        // Use JUnit Platform for unit tests.
        useJUnitPlatform()

        reports {
            // XML reports for GitLab CI.
            junitXml.required.set(true)
            // HTML reports to view with a webbrowser.
            html.required.set(true)
        }

        // Mockito JDK21+ config
        // https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#mockito-instrumentation
        jvmArgs("-javaagent:${mockitoAgent.asPath}")
    }
}

// https://github.com/melix/jmh-gradle-plugin/blob/master/README.adoc#configuration-options
jmh {
    // Use latest JMH version (1.37, https://github.com/openjdk/jmh/tags)
    // instead of default (1.36, https://github.com/melix/jmh-gradle-plugin/blob/dfdbb0cd3a363e2dbbcaab93bb1be32178f4cae4/src/main/java/me/champeau/jmh/DefaultsConfigurer.java#L24)
    jmhVersion = latestJmhVersion // Specifies JMH version

    // Force GC (garbage collection) between iterations.
    //
    //  Forcing the GC may help to lower the noise in GC-heavy benchmarks, at the expense of jeopardizing GC ergonomics decisions. Use with care.
    // https://github.com/openjdk/jmh/blob/1be779e0b4af174b67abf8080d1b76dda570d88d/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java#L148-L152
    forceGC = true

    // If human output is saved, it won't be written to stdout while running the benchmark!
    //humanOutputFile = project.file("${project.layout.buildDirectory.get()}/reports/jmh/human.txt")

    resultsFile = project.file("${project.layout.buildDirectory.get()}/reports/jmh/results.txt")
    resultFormat = "CSV"

    excludes = listOf(
        // To skip JmhCgl or JmhCompetition, uncomment it below.
//        "de.uni_marburg.powersort.benchmark.JmhCgl.benchmark",
        "de.uni_marburg.powersort.benchmark.JmhCompetition.benchmark",
    )
}