/*
 * 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.Paths
import java.nio.file.Files

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"
}


ext.dtestJar = System.getenv("DTEST_JAR") ?: "dtest-5.1.jar" // trunk is currently 5.0.jar - update when trunk moves
println("Using DTest jar: ${ext.dtestJar}")

// 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()
    }

    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"
    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')

    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-configuration2', version: '2.7')

    runtimeOnly group: 'commons-beanutils', name: 'commons-beanutils', version: '1.9.3'
    runtimeOnly group: 'org.yaml', name: 'snakeyaml', version: '1.26'

    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(files("dtest-jars/${dtestJar}"))
    integrationTestImplementation("org.apache.cassandra:dtest-api:0.0.15")
    // 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")
    }
    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 = "8g"
}

// 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"))
}

integrationTest.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)
}
