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


import com.github.spotbugs.SpotBugsTask
import org.nosphere.apache.rat.RatTask

import java.nio.file.Files
import java.nio.file.Paths

buildscript {
    dependencies {
        // findBugs needs a newer version of Guava in the buildscript.
        // otherwise it throws an exception
        classpath "com.google.guava:guava:28.2-jre"
    }
}

plugins {
    id 'idea'
    id 'java'
    id 'java-test-fixtures'
    id 'application'
    id 'maven-publish'

    // since we're using a specific version here, we delay applying the plugin till the all projects
    id "com.github.spotbugs" version "3.0.0" apply false

    // https://github.com/nebula-plugins/gradle-ospackage-plugin/wiki
    id "nebula.ospackage" version "8.3.0"
    id 'nebula.ospackage-application' version "8.3.0"
    id 'com.google.cloud.tools.jib' version '2.2.0'
    id 'org.asciidoctor.jvm.convert' version '3.1.0'

    // Release Audit Tool (RAT) plugin for checking project licenses
    id("org.nosphere.apache.rat") version "0.8.0"
}

println("Using DTest jar: ${dtestVersion}")

def integrationMaxHeapSize = System.getenv("INTEGRATION_MAX_HEAP_SIZE") ?: "8g"
println("Using ${integrationMaxHeapSize} maxHeapSize")

def integrationMaxParallelForks = (System.getenv("INTEGRATION_MAX_PARALLEL_FORKS") ?: "4") as int
println("Using ${integrationMaxParallelForks} maxParallelForks")

// Force checkstyle, rat, and spotBugs to run before test tasks for faster feedback
def codeCheckTasks = task("codeCheckTasks")

allprojects {
    apply plugin: 'jacoco'
    apply plugin: 'checkstyle'
    apply plugin: "com.github.spotbugs"

    repositories {
        mavenCentral()

        // for dtest jar
        mavenLocal()
    }

    checkstyle {
        toolVersion '7.8.1'
        configFile file("${project.rootDir}/checkstyle.xml")
    }
    spotbugs {
        toolVersion = '4.2.3'
        excludeFilter = file("${project.rootDir}/spotbugs-exclude.xml")
    }

    tasks.withType(SpotBugsTask) {
        reports.xml.enabled = false
        reports.html.enabled = true
    }

    codeCheckTasks.dependsOn(tasks.withType(Checkstyle))
    codeCheckTasks.dependsOn(tasks.withType(RatTask))
    codeCheckTasks.dependsOn(tasks.withType(SpotBugsTask))

    tasks.withType(Test) {
        shouldRunAfter(codeCheckTasks)
        shouldRunAfter(tasks.withType(Checkstyle))
        shouldRunAfter(tasks.withType(RatTask))
        shouldRunAfter(tasks.withType(SpotBugsTask))
    }

}

group 'org.apache.cassandra'
version project.version

sourceCompatibility = 1.8

// Take the application out once we're running via Cassandra
mainClassName = "org.apache.cassandra.sidecar.CassandraSidecarDaemon"
applicationName = 'cassandra-sidecar'

// Config file location should be in file:/// format for local files,
def confFile = "file:" + File.separator + File.separator + "APP_HOME_TO_REPLACE/conf/sidecar.yaml"

applicationDefaultJvmArgs = ["-Dsidecar.logdir=./logs",
                             "-Dsidecar.config=" + confFile,
                             "-Dlogback.configurationFile=./conf/logback.xml",
                             "-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory",
                             "-javaagent:APP_HOME_TO_REPLACE/agents/jolokia-jvm-1.6.0-agent.jar=port=7777,host=localhost"]
startScripts {
    doLast {
        unixScript.text = unixScript.text.replace("APP_HOME_TO_REPLACE", "\${APP_HOME}")
    }
}

run {
    confFile = "file:" + File.separator + File.separator + "$projectDir/conf/sidecar.yaml"
    println "Sidecar configuration file $confFile"
    jvmArgs = ["-Dsidecar.logdir=./logs",
               "-Dsidecar.config=" + confFile,
               "-Dlogback.configurationFile=./conf/logback.xml",
               "-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory",
               "-javaagent:$projectDir/agents/jolokia-jvm-1.6.0-agent.jar=port=7777,host=localhost"]
}

// add integration test
sourceSets {
    integrationTest {
        java {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir file('src/test/integration')
        }
    }
}

// and mark it as test root
idea {
    module {
        testSourceDirs += sourceSets.integrationTest.java.srcDirs
    }
}

configurations {
    jolokia

    integrationTestImplementation.extendsFrom testImplementation

    runtime.exclude(group: "com.google.code.findbugs", module: "jsr305")
    runtime.exclude(group: "org.codehaus.mojo", module: "animal-sniffer-annotations")
    runtime.exclude(group: "com.google.guava", module: "listenablefuture")
    runtime.exclude(group: "org.checkerframework", module: "checker-qual")
    runtime.exclude(group: "com.google.errorprone", module: "error_prone_annotations")
    runtime.exclude(group: 'com.github.jnr', module: 'jnr-ffi')
    runtime.exclude(group: 'com.github.jnr', module: 'jnr-posix')
}

dependencies {
    compileOnly('org.jetbrains:annotations:23.0.0')
    testCompileOnly('org.jetbrains:annotations:23.0.0')
    integrationTestCompileOnly('org.jetbrains:annotations:23.0.0')

    implementation("io.vertx:vertx-web:${project.vertxVersion}") {
        exclude group: 'junit', module: 'junit'
    }
    implementation("io.vertx:vertx-dropwizard-metrics:${project.vertxVersion}")
    implementation("io.vertx:vertx-web-client:${project.vertxVersion}")

    implementation('com.datastax.cassandra:cassandra-driver-core:3.11.3')
    implementation('com.google.inject:guice:4.2.2')
    implementation("com.github.ben-manes.caffeine:caffeine:2.9.3")

    // Trying to be exactly compatible with Cassandra's deps
    implementation("org.slf4j:slf4j-api:${project.slf4jVersion}")
    implementation('ch.qos.logback:logback-core:1.2.3')
    implementation('ch.qos.logback:logback-classic:1.2.3')

    implementation(group: 'org.apache.commons', name: 'commons-lang3', version: '3.13.0')

    // Jackson for yaml-based configuration parsing
    implementation(group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "${project.jacksonVersion}")
    implementation(group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: "${project.jacksonVersion}")

    jolokia 'org.jolokia:jolokia-jvm:1.6.0:agent'

    testImplementation "org.junit.jupiter:junit-jupiter-api:${project.junitVersion}"
    testImplementation "org.junit.jupiter:junit-jupiter-params:${project.junitVersion}"
    testImplementation "org.assertj:assertj-core:3.24.2"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${project.junitVersion}"

    testImplementation('com.google.guava:guava-testlib:31.1-jre') {
        exclude group: 'junit', module: 'junit'
    }

    testImplementation('com.datastax.cassandra:cassandra-driver-core:3.9.0:tests')
    testImplementation('org.mockito:mockito-core:4.10.0')
    testImplementation('org.mockito:mockito-inline:4.10.0')
    testImplementation("io.vertx:vertx-junit5:${project.vertxVersion}")
    testImplementation(testFixtures(project(":common")))

    implementation(project(":common"))
    implementation(project(":adapters:base"))

    testFixturesApi(testFixtures(project(":common")))
    testFixturesImplementation("io.vertx:vertx-junit5:${project.vertxVersion}")
    testFixturesImplementation('com.google.inject:guice:4.2.2')
    testFixturesImplementation('org.mockito:mockito-core:4.10.0')
    testFixturesImplementation("org.junit.jupiter:junit-jupiter-api:${project.junitVersion}")
    testFixturesImplementation("org.junit.jupiter:junit-jupiter-params:${project.junitVersion}")
    testFixturesImplementation("org.assertj:assertj-core:3.24.2")
    testFixturesImplementation("io.vertx:vertx-web:${project.vertxVersion}") {
        exclude group: 'junit', module: 'junit'
    }
    integrationTestImplementation(group: 'org.apache.cassandra', name: "${dtestDependencyName}", version: "${dtestVersion}")
    integrationTestImplementation(group: 'org.apache.cassandra', name: 'dtest-api', version: "${dtestApiVersion}")
    // Needed by the Cassandra dtest framework
    integrationTestImplementation("org.junit.vintage:junit-vintage-engine:${junitVersion}")
}

jar {
    doFirst {
        // Store current Cassandra Sidecar build version in an embedded resource file;
        // the file is either created or overwritten, and ignored by Git source control
        Files.createDirectories(Paths.get("$projectDir/common/src/main/resources"))
        new File("$projectDir/common/src/main/resources/sidecar.version").text = version
    }
}

java {
    withJavadocJar()
    withSourcesJar()
}

publishing {
    publications {
        maven(MavenPublication) {
            from components.java
            groupId project.group
            artifactId "${archivesBaseName}"
            version System.getenv("CODE_VERSION") ?: "${version}"
        }
    }
}

task copyIdeaSettings(type: Copy) {
    from "ide/idea"
    into ".idea"
}

tasks.named('idea').configure {
    dependsOn copyIdeaSettings
}

// Lets copy the distributions from build/install directory to /bin and /lib
// directories to be aligned with C* distribution format
task copyDist(type: Copy) {
    from "$buildDir/install/$applicationName"
    into "$projectDir"
}

task copyJolokia(type: Copy) {
    from configurations.jolokia
    into "$projectDir/src/main/dist/agents"
}

// Lets clean distribution directories along with default build directories.
clean.doLast {
    ["agents", "bin", "conf", "lib"].each {
        println "Deleting directory $projectDir/$it"
        delete "$projectDir/$it"
    }
    println "Deleting generated docs $projectDir/src/main/resources/docs"
    delete "$projectDir/src/main/resources/docs"
}

test {
    systemProperty "vertxweb.environment", "dev"
    // ordinarily we don't need integration tests
    // see the integrationTest task
    useJUnitPlatform()
    reports {
        junitXml.enabled = true
        def destDir = Paths.get(rootProject.rootDir.absolutePath, "build", "test-results", "test").toFile()
        println("Destination directory for unit tests: ${destDir}")
        junitXml.destination = destDir
        html.enabled = true
    }
    testLogging {
        events "passed", "skipped", "failed"
    }
}

tasks.register("integrationTest", Test) {
    if (JavaVersion.current().isJava11Compatible()) {
        def JDK11_OPTIONS = ['-Djdk.attach.allowAttachSelf=true',
                             '--add-exports', 'java.base/jdk.internal.misc=ALL-UNNAMED',
                             '--add-exports', 'java.base/jdk.internal.ref=ALL-UNNAMED',
                             '--add-exports', 'java.base/sun.nio.ch=ALL-UNNAMED',
                             '--add-exports', 'java.management.rmi/com.sun.jmx.remote.internal.rmi=ALL-UNNAMED',
                             '--add-exports', 'java.rmi/sun.rmi.registry=ALL-UNNAMED',
                             '--add-exports', 'java.rmi/sun.rmi.server=ALL-UNNAMED',
                             '--add-exports', 'java.sql/java.sql=ALL-UNNAMED',
                             '--add-opens', 'java.base/java.lang.module=ALL-UNNAMED',
                             '--add-opens', 'java.base/jdk.internal.loader=ALL-UNNAMED',
                             '--add-opens', 'java.base/jdk.internal.ref=ALL-UNNAMED',
                             '--add-opens', 'java.base/jdk.internal.reflect=ALL-UNNAMED',
                             '--add-opens', 'java.base/jdk.internal.math=ALL-UNNAMED',
                             '--add-opens', 'java.base/jdk.internal.module=ALL-UNNAMED',
                             '--add-opens', 'java.base/jdk.internal.util.jar=ALL-UNNAMED',
                             '--add-opens', 'jdk.management/com.sun.management.internal=ALL-UNNAMED']
        jvmArgs(JDK11_OPTIONS)
        println("JVM arguments for $project.name are $allJvmArgs")
    }
    // Disable direct memory allocator as it doesn't release properly
    systemProperty "cassandra.netty_use_heap_allocator", "true"
    systemProperty "vertxweb.environment", "dev"
    // Because tests are forked, we need to explicitly pass the system property from the
    // Gradle JVM down to the children

    def versionsToTest = System.getProperty("cassandra.sidecar.versions_to_test", null)
    if (versionsToTest != "" && versionsToTest != null) {
        systemProperty "cassandra.sidecar.versions_to_test", versionsToTest
    }
    jacoco {
        enabled = false
    }
    useJUnitPlatform() {
        includeTags "integrationTest"
    }
    reports {
        junitXml.enabled = true
        def destDir = Paths.get(rootProject.rootDir.absolutePath, "build", "test-results", "integration").toFile()
        println("Destination directory for integration tests: ${destDir}")
        junitXml.destination = destDir
        html.enabled = true
    }
    testLogging {
        events "passed", "skipped", "failed"
    }
    testClassesDirs = sourceSets.integrationTest.output.classesDirs
    classpath = sourceSets.integrationTest.runtimeClasspath
    shouldRunAfter test
    forkEvery = 1 // DTest framework tends to have issues without forkEvery test class
    maxHeapSize = integrationMaxHeapSize
    maxParallelForks = integrationMaxParallelForks
}

// copy the user documentation to the final build
task copyDocs(type: Copy, dependsOn: ':docs:asciidoctor') {
    from(tasks.getByPath(":docs:asciidoctor").outputs) {
        include "**/*.html"
    }
    into "build/docs/"
    exclude "tmp"
}

/**
 * General configuration for linux packages.
 * Can be overridden in the buildRpm and buildDeb configuration
 * We can put dependencies here, such as java, but unfortunately since java is distributed
 * in an inconsistent manner depending on the version you want (8 vs 11) we can't include Java
 * as a requirement without the install breaking if you want to use a different version
 */
ospackage {
    packageName = "cassandra-sidecar"
    version = project.version
    // ospackage puts packages into /opt/[package] by default
    // which is _technically_ the right spot for packages
    link("/usr/local/bin/cassandra-sidecar", "/opt/cassandra-sidecar/bin/cassandra-sidecar")
    license "Apache License 2.0"
    description "Sidecar Management Tool for Apache Cassandra"
    os = LINUX
    user "root"
}

buildRpm {
    group = "build"
}

buildDeb {
    group = "build"
}

applicationDistribution.from("LICENSE.txt") {
    into ""
}

tasks.register('buildIgnoreRatList', Exec) {
    description 'Builds a list of ignored files for the rat task from the unversioned git files'
    commandLine 'bash', '-c', "git clean --force -d --dry-run -x | cut -c 14-"
    doFirst {
        standardOutput new FileOutputStream("${buildDir}/.rat-excludes.txt")
    }
    // allows task to fail when git/cut commands are unavailable or fail
    ignoreExitValue = true
}

rat {
    doFirst {
        def excludeFilePath = Paths.get("${buildDir}/.rat-excludes.txt")
        def excludeLines = Files.readAllLines(excludeFilePath)
        excludeLines.each { line ->
            if (line.endsWith("/")) {
                excludes.add("**/" + line + "**")
            } else {
                excludes.add(line)
            }
        }
    }

    // List of Gradle exclude directives, defaults to ['**/.gradle/**']
    excludes.add("**/build/**")
    excludes.add("CHANGES.txt")

    // Documentation files
    excludes.add("**/docs/src/**")
    // gradle files
    excludes.add("gradle/**")
    excludes.add("gradlew")
    excludes.add("gradlew.bat")

    // resource files for test
    excludes.add("**/test**/resources/**")

    // XML, TXT and HTML reports directory, defaults to 'build/reports/rat'
    reportDir.set(file("build/reports/rat"))
}

compileIntegrationTestJava.onlyIf { "true" != System.getenv("skipIntegrationTest") }
checkstyleIntegrationTest.onlyIf { "true" != System.getenv("skipIntegrationTest") }
spotbugsIntegrationTest.onlyIf { "true" != System.getenv("skipIntegrationTest") }

// copyDist gets called on every build
copyDist.dependsOn installDist, copyJolokia
check.dependsOn codeCheckTasks, integrationTest, jacocoTestReport
build.dependsOn copyDist, copyJolokia, copyDocs
run.dependsOn build

tasks.named('rat').configure {
    dependsOn(buildIgnoreRatList)
}
