/*
 * 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 com.github.vlsi.gradle.crlf.CrLfSpec
import com.github.vlsi.gradle.crlf.LineEndings
import com.github.vlsi.gradle.dsl.configureEach
import com.github.vlsi.gradle.git.FindGitAttributes
import com.github.vlsi.gradle.git.dsl.gitignore
import com.github.vlsi.gradle.properties.dsl.lastEditYear
import com.github.vlsi.gradle.properties.dsl.props
import com.github.vlsi.gradle.release.RepositoryType
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApisExtension
import java.net.URI
import net.ltgt.gradle.errorprone.errorprone
import org.apache.calcite.buildtools.buildext.dsl.ParenthesisBalancer
import org.gradle.api.tasks.testing.logging.TestExceptionFormat

plugins {
    // java-base is needed for platform(...) resolution,
    // see https://github.com/gradle/gradle/issues/14822
    `java-base`
    publishing
    // Verification
    checkstyle
    calcite.buildext
    jacoco
    id("jacoco-report-aggregation")
    id("org.checkerframework") apply false
    id("com.github.autostyle")
    id("org.nosphere.apache.rat")
    id("com.github.spotbugs")
    id("de.thetaphi.forbiddenapis") apply false
    id("net.ltgt.errorprone") apply false
    id("com.github.vlsi.jandex") apply false
    id("org.owasp.dependencycheck")
    id("com.github.johnrengelman.shadow") apply false
    id("org.sonarqube")
    // IDE configuration
    id("org.jetbrains.gradle.plugin.idea-ext")
    id("com.github.vlsi.ide")
    // Release
    id("com.github.vlsi.crlf")
    id("com.github.vlsi.gradle-extensions")
    id("com.github.vlsi.license-gather") apply false
    id("com.github.vlsi.stage-vote-release")
    id("com.autonomousapps.dependency-analysis") apply false
}

repositories {
    // At least for RAT
    mavenCentral()
}

tasks.wrapper {
    distributionType = Wrapper.DistributionType.BIN
    doLast {
        val sha256Uri = URI("$distributionUrl.sha256")
        val sha256Sum = String(sha256Uri.toURL().readBytes())
        propertiesFile.appendText("distributionSha256Sum=${sha256Sum}\n")
    }
}

fun reportsForHumans() = !(System.getenv()["CI"]?.toBoolean() ?: false)

val lastEditYear by extra(lastEditYear())

// Do not enable spotbugs by default. Execute it only when -Pspotbugs is present
val enableSpotBugs = props.bool("spotbugs")
val enableCheckerframework by props()
val enableErrorprone by props()
val enableDependencyAnalysis by props()
val enableJacoco by props()
val skipJandex by props()
val skipCheckstyle by props()
val skipAutostyle by props()
val skipJavadoc by props()
val enableMavenLocal by props()
val enableGradleMetadata by props()
val werror by props(true) // treat javac warnings as errors
// Inherited from stage-vote-release-plugin: skipSign, useGpgCmd
// Inherited from gradle-extensions-plugin: slowSuiteLogThreshold=0L, slowTestLogThreshold=2000L

// Java versions prior to 1.8.0u202 have known issues that cause invalid bytecode in certain patterns
// of annotation usage.
// So we require at least 1.8.0u202
System.getProperty("java.version").let { version ->
    version.takeIf { it.startsWith("1.8.0_") }
        ?.removePrefix("1.8.0_")
        ?.toIntOrNull()
        ?.let {
            require(it >= 202) {
                "Apache Calcite requires Java 1.8.0u202 or later. The current Java version is $version"
            }
        }
}

ide {
    copyrightToAsf()
    ideaInstructionsUri =
        uri("https://calcite.apache.org/docs/howto.html#setting-up-intellij-idea")
    doNotDetectFrameworks("android", "jruby")
}

// This task scans the project for gitignore / gitattributes, and that is reused for building
// source/binary artifacts with the appropriate eol/executable file flags
// It enables to automatically exclude patterns from .gitignore
val gitProps by tasks.registering(FindGitAttributes::class) {
    // Scanning for .gitignore and .gitattributes files in a task avoids doing that
    // when distribution build is not required (e.g. code is just compiled)
    root.set(rootDir)
}

val rat by tasks.getting(org.nosphere.apache.rat.RatTask::class) {
    gitignore(gitProps)
    verbose.set(true)
    // Note: patterns are in non-standard syntax for RAT, so we use exclude(..) instead of excludeFile
    exclude(rootDir.resolve(".ratignore").readLines())
}

tasks.validateBeforeBuildingReleaseArtifacts {
    dependsOn(rat)
}

val String.v: String get() = rootProject.extra["$this.version"] as String

val buildVersion = "calcite".v + releaseParams.snapshotSuffix

println("Building Apache Calcite $buildVersion")

releaseArtifacts {
    fromProject(":release")
}

// Configures URLs to SVN and Nexus
releaseParams {
    tlp.set("Calcite")
    componentName.set("Apache Calcite")
    releaseTag.set("calcite-$buildVersion")
    rcTag.set(rc.map { "calcite-$buildVersion-rc$it" })
    sitePreviewEnabled.set(false)
    nexus {
        // https://github.com/marcphilipp/nexus-publish-plugin/issues/35
        packageGroup.set("org.apache.calcite")
        if (repositoryType.get() == RepositoryType.PROD) {
            // org.apache.calcite at repository.apache.org
            stagingProfileId.set("778fd0d4358bb")
        }
    }
    svnDist {
        staleRemovalFilters {
            includes.add(Regex(".*apache-calcite-\\d.*"))
            validates.empty()
            validates.add(provider {
                Regex("release/calcite/apache-calcite-${version.toString().removeSuffix("-SNAPSHOT")}")
            })
        }
    }
}

reporting {
    reports {
        if (enableJacoco) {
            val jacocoAggregateTestReport by creating(JacocoCoverageReport::class) {
                testType.set(TestSuiteType.UNIT_TEST)
            }
        }
    }
}

val javadocAggregate by tasks.registering(Javadoc::class) {
    group = JavaBasePlugin.DOCUMENTATION_GROUP
    description = "Generates aggregate javadoc for all the artifacts"

    val sourceSets = subprojects
        .mapNotNull { it.extensions.findByType<SourceSetContainer>() }
        .filter { it.names.contains("main") }
        .map { it.named("main") }

    classpath = files(sourceSets.map { set -> set.map { it.output + it.compileClasspath } })
    setSource(sourceSets.map { set -> set.map { it.allJava } })
    setDestinationDir(file("$buildDir/docs/javadocAggregate"))
}

/** Similar to {@link #javadocAggregate} but includes tests.
 * CI uses this target to validate javadoc (e.g. checking for broken links). */
val javadocAggregateIncludingTests by tasks.registering(Javadoc::class) {
    description = "Generates aggregate javadoc for all the artifacts"

    val sourceSets = subprojects
        .filter { it.name != "bom" }
        .mapNotNull { it.extensions.findByType<SourceSetContainer>() }
        .flatMap { listOf(it.named("main"), it.named("test")) }

    classpath = files(sourceSets.map { set -> set.map { it.output + it.compileClasspath } })
    setSource(sourceSets.map { set -> set.map { it.allJava } })
    setDestinationDir(file("$buildDir/docs/javadocAggregateIncludingTests"))
}

val adaptersForSqlline = listOf(
    ":babel", ":cassandra", ":druid", ":elasticsearch",
    ":file", ":geode", ":innodb", ":kafka", ":mongodb",
    ":pig", ":piglet", ":plus", ":redis", ":spark", ":splunk")

val dataSetsForSqlline = listOf(
    "net.hydromatic:foodmart-data-hsqldb",
    "net.hydromatic:scott-data-hsqldb",
    "net.hydromatic:chinook-data-hsqldb"
)

val sqllineClasspath by configurations.creating {
    isCanBeConsumed = false
    attributes {
        attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
        attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.CLASSES_AND_RESOURCES))
        attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, JavaVersion.current().majorVersion.toInt())
        attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
    }
}

dependencies {
    sqllineClasspath(platform(project(":bom")))
    sqllineClasspath(project(":testkit"))
    sqllineClasspath("sqlline:sqlline")
    for (p in adaptersForSqlline) {
        sqllineClasspath(project(p))
    }
    for (m in dataSetsForSqlline) {
        sqllineClasspath(module(m))
    }
    if (enableJacoco) {
        for (p in subprojects) {
            jacocoAggregation(p)
        }
    }
}

val buildSqllineClasspath by tasks.registering(Jar::class) {
    description = "Creates classpath-only jar for running SqlLine"
    // One can debug classpath with ./gradlew dependencies --configuration sqllineClasspath
    inputs.files(sqllineClasspath).withNormalizer(ClasspathNormalizer::class.java)
    archiveFileName.set("sqllineClasspath.jar")
    manifest {
        attributes(
            "Main-Class" to "sqlline.SqlLine",
            "Class-Path" to provider {
                // Class-Path is a list of URLs
                sqllineClasspath.joinToString(" ") {
                    it.toURI().toURL().toString()
                }
            }
        )
    }
}

if (enableDependencyAnalysis) {
    apply(plugin = "com.autonomousapps.dependency-analysis")
    configure<com.autonomousapps.DependencyAnalysisExtension> {
        // See https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin
        // Most of the time the recommendations are good, however, there are cases the suggestsions
        // are off, so we don't include the dependency analysis to CI workflow yet
        // ./gradlew -PenableDependencyAnalysis buildHealth --no-parallel --no-daemon
        issues {
            all { // all projects
                onAny {
                    severity("fail")
                }
                onRedundantPlugins {
                    severity("ignore")
                }
            }
        }
    }
}

val javaccGeneratedPatterns = arrayOf(
    "org/apache/calcite/jdbc/CalciteDriverVersion.java",
    "**/parser/**/*ParserImpl.*",
    "**/parser/**/*ParserImplConstants.*",
    "**/parser/**/*ParserImplTokenManager.*",
    "**/parser/**/PigletParser.*",
    "**/parser/**/PigletParserConstants.*",
    "**/parser/**/ParseException.*",
    "**/parser/**/SimpleCharStream.*",
    "**/parser/**/Token.*",
    "**/parser/**/TokenMgrError.*",
    "**/org/apache/calcite/runtime/Resources.java",
    "**/parser/**/*ParserTokenManager.*"
)

fun PatternFilterable.excludeJavaCcGenerated() {
    exclude(*javaccGeneratedPatterns)
}

fun com.github.autostyle.gradle.BaseFormatExtension.license() {
    licenseHeader(rootProject.ide.licenseHeader) {
        copyrightStyle("bat", com.github.autostyle.generic.DefaultCopyrightStyle.PAAMAYIM_NEKUDOTAYIM)
        copyrightStyle("cmd", com.github.autostyle.generic.DefaultCopyrightStyle.PAAMAYIM_NEKUDOTAYIM)
    }
    trimTrailingWhitespace()
    endWithNewline()
}

sonarqube {
    properties {
        property("sonar.test.inclusions", "**/*Test*/**")
        property("sonar.coverage.jacoco.xmlReportPaths", "$buildDir/reports/jacoco/jacocoAggregateTestReport/jacocoAggregateTestReport.xml")
    }
}

allprojects {
    group = "org.apache.calcite"
    version = buildVersion

    apply(plugin = "com.github.vlsi.gradle-extensions")

    repositories {
        // RAT and Autostyle dependencies
        mavenCentral()
    }

    val javaUsed = file("src/main/java").isDirectory
    if (javaUsed) {
        apply(plugin = "java-library")
        configurations {
            "implementation" {
                exclude(group = "org.jetbrains", module = "annotations")
            }
        }
    }

    plugins.withId("java-library") {
        dependencies {
            "annotationProcessor"(platform(project(":bom")))
            "implementation"(platform(project(":bom")))
            "testAnnotationProcessor"(platform(project(":bom")))
        }
    }

    val hasTests = file("src/test/java").isDirectory || file("src/test/kotlin").isDirectory
    if (hasTests) {
        // Add default tests dependencies
        dependencies {
            val testImplementation by configurations
            val testRuntimeOnly by configurations
            testImplementation(platform("org.junit:junit-bom"))
            testImplementation("org.junit.jupiter:junit-jupiter")
            testImplementation("org.hamcrest:hamcrest")
            if (project.props.bool("junit4", default = false)) {
                // Allow projects to opt-out of junit dependency, so they can be JUnit5-only
                testImplementation("junit:junit")
                testRuntimeOnly("org.junit.vintage:junit-vintage-engine")
            }
        }
        if (enableJacoco) {
            apply(plugin = "jacoco")
        }
    }

    if (!skipAutostyle) {
        apply(plugin = "com.github.autostyle")
        autostyle {
            kotlinGradle {
                license()
                ktlint()
            }
            format("configs") {
                filter {
                    include("**/*.sh", "**/*.bsh", "**/*.cmd", "**/*.bat")
                    include("**/*.properties", "**/*.yml")
                    include("**/*.xsd", "**/*.xsl", "**/*.xml")
                    include("**/*.fmpp", "**/*.ftl", "**/*.jj")
                    // Autostyle does not support gitignore yet https://github.com/autostyle/autostyle/issues/13
                    exclude("bin/**", "out/**", "target/**", "gradlew*")
                    exclude(rootDir.resolve(".ratignore").readLines())
                }
                license()
                endWithNewline()
            }
            format("web") {
                filter {
                    include("**/*.md", "**/*.html")
                    exclude("**/test/**/*.html")
                }
                trimTrailingWhitespace()
                endWithNewline()
            }
            if (project == rootProject) {
                // Spotless does not exclude subprojects when using target(...)
                // So **/*.md is enough to scan all the md files in the codebase
                // See https://github.com/diffplug/spotless/issues/468
                format("markdown") {
                    filter.include("**/*.md")
                    // Flot is known to have trailing whitespace, so the files
                    // are kept in their original format (e.g. to simplify diff on library upgrade)
                    endWithNewline()
                }
            }
        }
        plugins.withId("org.jetbrains.kotlin.jvm") {
            autostyle {
                kotlin {
                    licenseHeader(rootProject.ide.licenseHeader)
                    ktlint {
                        userData(mapOf("disabled_rules" to "import-ordering"))
                    }
                    trimTrailingWhitespace()
                    endWithNewline()
                }
            }
        }
    }
    if (!skipCheckstyle) {
        apply<CheckstylePlugin>()
        // This will be config_loc in Checkstyle (checker.xml)
        val configLoc = File(rootDir, "src/main/config/checkstyle")
        checkstyle {
            toolVersion = "checkstyle".v
            isShowViolations = true
            configDirectory.set(configLoc)
            configFile = configDirectory.get().file("checker.xml").asFile
        }
        tasks.register("checkstyleAll") {
            dependsOn(tasks.withType<Checkstyle>())
        }
        tasks.configureEach<Checkstyle> {
            // Excludes here are faster than in suppressions.xml
            // Since here we can completely remove file from the analysis.
            // On the other hand, supporessions.xml still analyzes the file, and
            // then it recognizes it should suppress all the output.
            excludeJavaCcGenerated()
            // Workaround for https://github.com/gradle/gradle/issues/13927
            // Absolute paths must not be used as they defeat Gradle build cache
            // Unfortunately, Gradle passes only config_loc variable by default, so we make
            // all the paths relative to config_loc
            configProperties!!["cache_file"] =
                buildDir.resolve("checkstyle/cacheFile").relativeTo(configLoc)
        }
        // afterEvaluate is to support late sourceSet addition (e.g. jmh sourceset)
        afterEvaluate {
            tasks.configureEach<Checkstyle> {
                // Checkstyle 8.26 does not need classpath, see https://github.com/gradle/gradle/issues/14227
                classpath = files()
            }
        }
    }
    if (!skipAutostyle || !skipCheckstyle) {
        tasks.register("style") {
            group = LifecycleBasePlugin.VERIFICATION_GROUP
            description = "Formats code (license header, import order, whitespace at end of line, ...) and executes Checkstyle verifications"
            if (!skipAutostyle) {
                dependsOn("autostyleApply")
            }
            if (!skipCheckstyle) {
                dependsOn("checkstyleAll")
            }
        }
    }

    tasks.configureEach<AbstractArchiveTask> {
        // Ensure builds are reproducible
        isPreserveFileTimestamps = false
        isReproducibleFileOrder = true
        dirMode = "775".toInt(8)
        fileMode = "664".toInt(8)
    }

    tasks {
        configureEach<Javadoc> {
            excludeJavaCcGenerated()
            (options as StandardJavadocDocletOptions).apply {
                // Please refrain from using non-ASCII chars below since the options are passed as
                // javadoc.options file which is parsed with "default encoding"
                noTimestamp.value = true
                showFromProtected()
                // javadoc: error - The code being documented uses modules but the packages
                // defined in https://docs.oracle.com/en/java/javase/17/docs/api/ are in the unnamed module
                source = "1.8"
                docEncoding = "UTF-8"
                charSet = "UTF-8"
                encoding = "UTF-8"
                docTitle = "Apache Calcite API"
                windowTitle = "Apache Calcite API"
                header = "<b>Apache Calcite</b>"
                bottom =
                    "Copyright &copy; 2012-$lastEditYear Apache Software Foundation. All Rights Reserved."
                if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
                    addBooleanOption("html5", true)
                    links("https://docs.oracle.com/en/java/javase/17/docs/api/")
                } else {
                    links("https://docs.oracle.com/javase/8/docs/api/")
                }
            }
        }
    }

    plugins.withType<JavaPlugin> {
        configure<JavaPluginConvention> {
            sourceCompatibility = JavaVersion.VERSION_1_8
            targetCompatibility = JavaVersion.VERSION_1_8
        }
        configure<JavaPluginExtension> {
            consistentResolution {
                useCompileClasspathVersions()
            }
        }

        repositories {
            if (enableMavenLocal) {
                mavenLocal()
            }
            mavenCentral()
        }
        val sourceSets: SourceSetContainer by project

        apply(plugin = "de.thetaphi.forbiddenapis")
        apply(plugin = "maven-publish")

        if (!skipJandex) {
            apply(plugin = "com.github.vlsi.jandex")

            project.configure<com.github.vlsi.jandex.JandexExtension> {
                toolVersion.set("jandex".v)
                skipIndexFileGeneration()
            }
        }

        if (!enableGradleMetadata) {
            tasks.withType<GenerateModuleMetadata> {
                enabled = false
            }
        }

        if (!skipAutostyle) {
            autostyle {
                java {
                    filter.exclude(*javaccGeneratedPatterns +
                            "**/test/java/*.java" +
                            "**/RelRule.java" /** remove as part of CALCITE-4831 **/)
                    license()
                    if (!project.props.bool("junit4", default = false)) {
                        replace("junit5: Test", "org.junit.Test", "org.junit.jupiter.api.Test")
                        replaceRegex("junit5: Before", "org.junit.Before\\b", "org.junit.jupiter.api.BeforeEach")
                        replace("junit5: BeforeClass", "org.junit.BeforeClass", "org.junit.jupiter.api.BeforeAll")
                        replaceRegex("junit5: After", "org.junit.After\\b", "org.junit.jupiter.api.AfterEach")
                        replace("junit5: AfterClass", "org.junit.AfterClass", "org.junit.jupiter.api.AfterAll")
                        replace("junit5: Ignore", "org.junit.Ignore", "org.junit.jupiter.api.Disabled")
                        replaceRegex("junit5: @Before", "@Before\\b", "@BeforeEach")
                        replace("junit5: @BeforeClass", "@BeforeClass", "@BeforeAll")
                        replaceRegex("junit5: @After", "@After\\b", "@AfterEach")
                        replace("junit5: @AfterClass", "@AfterClass", "@AfterAll")
                        replace("junit5: @Ignore", "@Ignore", "@Disabled")
                        replace("junit5: Assert.assertThat", "org.junit.Assert.assertThat", "org.hamcrest.MatcherAssert.assertThat")
                        replace("junit5: Assert.fail", "org.junit.Assert.fail", "org.junit.jupiter.api.Assertions.fail")
                    }
                    replaceRegex("side by side comments", "(\n\\s*+[*]*+/\n)(/[/*])", "\$1\n\$2")
                    replaceRegex("jsr305 nullable -> checkerframework", "javax\\.annotation\\.Nullable", "org.checkerframework.checker.nullness.qual.Nullable")
                    replaceRegex("jsr305 nonnull -> checkerframework", "javax\\.annotation\\.Nonnull", "org.checkerframework.checker.nullness.qual.NonNull")
                    importOrder(
                        "org.apache.calcite.",
                        "org.apache.",
                        "au.com.",
                        "com.",
                        "io.",
                        "mondrian.",
                        "net.",
                        "org.",
                        "scala.",
                        "java",
                        "",
                        "static com.",
                        "static org.apache.calcite.",
                        "static org.apache.",
                        "static org.",
                        "static java",
                        "static "
                    )
                    removeUnusedImports()
                    replaceRegex("Avoid 2+ blank lines after package", "^package\\s+([^;]+)\\s*;\\n{3,}", "package \$1;\n\n")
                    replaceRegex("Avoid 2+ blank lines after import", "^import\\s+([^;]+)\\s*;\\n{3,}", "import \$1;\n\n")
                    indentWithSpaces(2)
                    replaceRegex("@Override should not be on its own line", "(@Override)\\s{2,}", "\$1 ")
                    replaceRegex("@Test should not be on its own line", "(@Test)\\s{2,}", "\$1 ")
                    replaceRegex("Newline in string should be at end of line", """\\n" *\+""", "\\\\n\"\n  +")
                    replaceRegex("require message for requireNonNull", """(?<!#)requireNonNull\(\s*(\w+)\s*(?:,\s*"(?!\1")\w+"\s*)?\)""", "requireNonNull($1, \"$1\")")
                    // (?-m) disables multiline, so $ matches the very end of the file rather than end of line
                    replaceRegex("Remove '// End file.java' trailer", "(?-m)\n// End [^\n]+\\.\\w+\\s*$", "")
                    replaceRegex("<p> should not be placed at the end of the line", "(?-m)\\s*+<p> *+\n \\* ", "\n *\n * <p>")
                    replaceRegex("Method parameter list should not end in whitespace or newline", "(?<!;)\\s+\\) \\{", ") {")
                    replaceRegex("Method argument list should not end in whitespace or newline", "(?<!;)\\s+(\\)[);,])", "$1")
                    replaceRegex("Method argument list should not end in whitespace or newline", "(?<!;)(\\s+)(\\)+)[.]", "$2$1.")
                    replaceRegex("Long assignment should be broken after '='", "^([^/*\"\\n]*) = ([^@\\n]*)\\(\n( *)", "$1 =\n$3$2(")
                    replaceRegex("Long assignment should be broken after '='", "^([^/*\"\\n]*) = ([^@\\n]*)\\((.*,)\n( *)", "$1 =\n$4$2($3 ")
                    // Assume developer copy-pasted the link, and updated text only, so the url is old, and we replace it with the proper one
                    replaceRegex(">[CALCITE-...] link styles: 1", "<a(?:(?!CALCITE-)[^>])++CALCITE-\\d+[^>]++>\\s*+\\[?(CALCITE-\\d+)\\]?", "<a href=\"https://issues.apache.org/jira/browse/\$1\">[\$1]")
                    // If the link was crafted manually, ensure it has [CALCITE-...] in the link text
                    replaceRegex(">[CALCITE-...] link styles: 2", "<a(?:(?!CALCITE-)[^>])++(CALCITE-\\d+)[^>]++>\\s*+\\[?CALCITE-\\d+\\]?", "<a href=\"https://issues.apache.org/jira/browse/\$1\">[\$1]")
                    replace("hamcrest: allOf", "org.hamcrest.core.AllOf.allOf", "org.hamcrest.CoreMatchers.allOf")
                    replace("hamcrest: aMapWithSize", "org.hamcrest.collection.IsMapWithSize.aMapWithSize", "org.hamcrest.Matchers.aMapWithSize")
                    replace("hamcrest: anyOf", "org.hamcrest.core.AnyOf.anyOf", "org.hamcrest.CoreMatchers.anyOf")
                    replace("hamcrest: containsString", "org.hamcrest.core.StringContains.containsString", "org.hamcrest.CoreMatchers.containsString")
                    replace("hamcrest: CoreMatchers", "import org.hamcrest.CoreMatchers;", "import static org.hamcrest.CoreMatchers.anything;")
                    replace("hamcrest: empty", "org.hamcrest.collection.IsEmptyCollection.empty", "org.hamcrest.Matchers.empty")
                    replace("hamcrest: emptyArray", "org.hamcrest.collection.IsArrayWithSize.emptyArray", "org.hamcrest.Matchers.emptyArray")
                    replace("hamcrest: endsWidth", "org.hamcrest.core.StringEndsWith.endsWith", "org.hamcrest.CoreMatchers.endsWith")
                    replace("hamcrest: equalTo", "org.hamcrest.core.IsEqual.equalTo", "org.hamcrest.CoreMatchers.equalTo")
                    replace("hamcrest: greaterThanOrEqualTo", "org.hamcrest.number.OrderingComparison.greaterThanOrEqualTo", "org.hamcrest.Matchers.greaterThanOrEqualTo")
                    replace("hamcrest: greaterThan", "org.hamcrest.number.OrderingComparison.greaterThan", "org.hamcrest.Matchers.greaterThan")
                    replace("hamcrest: hasItem", "org.hamcrest.core.IsIterableContaining.hasItem", "org.hamcrest.CoreMatchers.hasItem")
                    replace("hamcrest: hasItems", "org.hamcrest.core.IsIterableContaining.hasItems", "org.hamcrest.CoreMatchers.hasItems")
                    replace("hamcrest: hasSize", "org.hamcrest.collection.IsCollectionWithSize.hasSize", "org.hamcrest.Matchers.hasSize")
                    replace("hamcrest: hasToString", "org.hamcrest.object.HasToString.hasToString", "org.hamcrest.Matchers.hasToString")
                    replace("hamcrest: instanceOf", "org.hamcrest.core.IsInstanceOf.instanceOf", "org.hamcrest.CoreMatchers.instanceOf")
                    replace("hamcrest: instanceOf", "org.hamcrest.Matchers.instanceOf", "org.hamcrest.CoreMatchers.instanceOf")
                    replace("hamcrest: is", "org.hamcrest.core.Is.is", "org.hamcrest.CoreMatchers.is")
                    replace("hamcrest: is", "org.hamcrest.Matchers.is", "org.hamcrest.CoreMatchers.is")
                    replace("hamcrest: isA", "org.hamcrest.core.Is.isA", "org.hamcrest.CoreMatchers.isA")
                    replace("hamcrest: lessThanOrEqualTo", "org.hamcrest.number.OrderingComparison.lessThanOrEqualTo", "org.hamcrest.Matchers.lessThanOrEqualTo")
                    replace("hamcrest: lessThan", "org.hamcrest.number.OrderingComparison.lessThan", "org.hamcrest.Matchers.lessThan")
                    replace("hamcrest: Matchers", "import org.hamcrest.Matchers;", "import static org.hamcrest.Matchers.allOf;")
                    replace("hamcrest: notNullValue", "org.hamcrest.core.IsNull.notNullValue", "org.hamcrest.CoreMatchers.notNullValue")
                    replace("hamcrest: notNullValue", "org.hamcrest.Matchers.notNullValue", "org.hamcrest.CoreMatchers.notNullValue")
                    replace("hamcrest: not", "org.hamcrest.core.IsNot.not", "org.hamcrest.CoreMatchers.not")
                    replace("hamcrest: not", "org.hamcrest.Matchers.not", "org.hamcrest.CoreMatchers.not")
                    replace("hamcrest: nullValue", "org.hamcrest.core.IsNull.nullValue", "org.hamcrest.CoreMatchers.nullValue")
                    replace("hamcrest: nullValue", "org.hamcrest.Matchers.nullValue", "org.hamcrest.CoreMatchers.nullValue")
                    replace("hamcrest: sameInstance", "org.hamcrest.core.IsSame.sameInstance", "org.hamcrest.CoreMatchers.sameInstance")
                    replace("hamcrest: startsWith", "org.hamcrest.core.StringStartsWith.startsWith", "org.hamcrest.CoreMatchers.startsWith")
                    replaceRegex("hamcrest: size", "\\.size\\(\\), (is|equalTo)\\(", ", hasSize\\(")
                    custom("((() preventer", 1) { contents: String ->
                        ParenthesisBalancer.apply(contents)
                    }
                }
            }
        }
        if (enableSpotBugs) {
            apply(plugin = "com.github.spotbugs")
            spotbugs {
                toolVersion = "spotbugs".v
                reportLevel = "high"
                //  excludeFilter = file("$rootDir/src/main/config/spotbugs/spotbugs-filter.xml")
                // By default spotbugs verifies TEST classes as well, and we do not want that
                this.sourceSets = listOf(sourceSets["main"])
            }
            dependencies {
                // Parenthesis are needed here: https://github.com/gradle/gradle/issues/9248
                (constraints) {
                    "spotbugs"("org.ow2.asm:asm:${"asm".v}")
                    "spotbugs"("org.ow2.asm:asm-all:${"asm".v}")
                    "spotbugs"("org.ow2.asm:asm-analysis:${"asm".v}")
                    "spotbugs"("org.ow2.asm:asm-commons:${"asm".v}")
                    "spotbugs"("org.ow2.asm:asm-tree:${"asm".v}")
                    "spotbugs"("org.ow2.asm:asm-util:${"asm".v}")
                }
            }
        }

        configure<CheckForbiddenApisExtension> {
            failOnUnsupportedJava = false
            ignoreSignaturesOfMissingClasses = true
            suppressAnnotations.add("org.immutables.value.Generated")
            bundledSignatures.addAll(
                listOf(
                    "jdk-unsafe",
                    "jdk-deprecated",
                    "jdk-non-portable"
                )
            )
            signaturesFiles = files("$rootDir/src/main/config/forbidden-apis/signatures.txt")
        }

        if (enableErrorprone) {
            apply(plugin = "net.ltgt.errorprone")
            dependencies {
                "errorprone"("com.google.errorprone:error_prone_core:${"errorprone".v}")
                "annotationProcessor"("com.google.guava:guava-beta-checker:1.0")
            }
            tasks.withType<JavaCompile>().configureEach {
                options.errorprone {
                    disableWarningsInGeneratedCode.set(true)
                    errorproneArgs.add("-XepExcludedPaths:.*/javacc/.*")
                    enable(
                        "MethodCanBeStatic"
                    )
                    disable(
                        "ComplexBooleanConstant",
                        "EqualsGetClass",
                        "EqualsHashCode", // verified in Checkstyle
                        "OperatorPrecedence",
                        "MutableConstantField",
                        "ReferenceEquality",
                        "SameNameButDifferent",
                        "TypeParameterUnusedInFormals"
                    )
                    // Analyze issues, and enable the check
                    disable(
                        "BigDecimalEquals",
                        "DoNotCallSuggester",
                        "StringSplitter"
                    )
                }
            }
        }
        if (enableCheckerframework) {
            apply(plugin = "org.checkerframework")
            dependencies {
                "checkerFramework"("org.checkerframework:checker:${"checkerframework".v}")
                // CheckerFramework annotations might be used in the code as follows:
                // dependencies {
                //     "compileOnly"("org.checkerframework:checker-qual")
                //     "testCompileOnly"("org.checkerframework:checker-qual")
                // }
                if (JavaVersion.current() == JavaVersion.VERSION_1_8) {
                    // only needed for JDK 8
                    "checkerFrameworkAnnotatedJDK"("org.checkerframework:jdk8")
                }
            }
            configure<org.checkerframework.gradle.plugin.CheckerFrameworkExtension> {
                skipVersionCheck = true
                // See https://checkerframework.org/manual/#introduction
                checkers.add("org.checkerframework.checker.nullness.NullnessChecker")
                // Below checkers take significant time and they do not provide much value :-/
                // checkers.add("org.checkerframework.checker.optional.OptionalChecker")
                // checkers.add("org.checkerframework.checker.regex.RegexChecker")
                // https://checkerframework.org/manual/#creating-debugging-options-progress
                // extraJavacArgs.add("-Afilenames")
                extraJavacArgs.addAll(listOf("-Xmaxerrs", "10000"))
                // Consider Java assert statements for nullness and other checks
                extraJavacArgs.add("-AassumeAssertionsAreEnabled")
                // https://checkerframework.org/manual/#stub-using
                extraJavacArgs.add("-Astubs=" +
                        fileTree("$rootDir/src/main/config/checkerframework") {
                            include("**/*.astub")
                        }.asPath
                )
                if (project.path == ":core") {
                    extraJavacArgs.add("-AskipDefs=^org\\.apache\\.calcite\\.sql\\.parser\\.impl\\.")
                }
            }
        }

        tasks {
            configureEach<Jar> {
                manifest {
                    attributes["Bundle-License"] = "Apache-2.0"
                    attributes["Implementation-Title"] = "Apache Calcite"
                    attributes["Implementation-Version"] = project.version
                    attributes["Specification-Vendor"] = "The Apache Software Foundation"
                    attributes["Specification-Version"] = project.version
                    attributes["Specification-Title"] = "Apache Calcite"
                    attributes["Implementation-Vendor"] = "Apache Software Foundation"
                    attributes["Implementation-Vendor-Id"] = "org.apache.calcite"
                }
            }

            configureEach<CheckForbiddenApis> {
                excludeJavaCcGenerated()
                exclude(
                    "**/org/apache/calcite/adapter/os/Processes${'$'}ProcessFactory.class",
                    "**/org/apache/calcite/adapter/os/OsAdapterTest.class",
                    "**/org/apache/calcite/runtime/Resources${'$'}Inst.class",
                    "**/org/apache/calcite/util/TestUnsafe.class",
                    "**/org/apache/calcite/util/Unsafe.class",
                    "**/org/apache/calcite/test/Unsafe.class"
                )
            }

            configureEach<JavaCompile> {
                inputs.property("java.version", System.getProperty("java.version"))
                inputs.property("java.vm.version", System.getProperty("java.vm.version"))
                options.encoding = "UTF-8"
                options.compilerArgs.add("-Xlint:deprecation")
                if (werror) {
                    options.compilerArgs.add("-Werror")
                }
                if (enableCheckerframework) {
                    options.forkOptions.memoryMaximumSize = "2g"
                }
            }
            configureEach<Test> {
                outputs.cacheIf("test results depend on the database configuration, so we souldn't cache it") {
                    false
                }
                useJUnitPlatform {
                    excludeTags("slow")
                }
                testLogging {
                    exceptionFormat = TestExceptionFormat.FULL
                    showStandardStreams = true
                }
                exclude("**/*Suite*")
                jvmArgs("-Xmx1536m")
                jvmArgs("-Djdk.net.URLClassPath.disableClassPathURLCheck=true")
                // Pass the property to tests
                fun passProperty(name: String, default: String? = null) {
                    val value = System.getProperty(name) ?: default
                    value?.let { systemProperty(name, it) }
                }
                passProperty("java.awt.headless")
                passProperty("junit.jupiter.execution.parallel.enabled", "true")
                passProperty("junit.jupiter.execution.parallel.mode.default", "concurrent")
                passProperty("junit.jupiter.execution.timeout.default", "5 m")
                passProperty("user.language", "TR")
                passProperty("user.country", "tr")
                passProperty("user.timezone", "UTC")
                val props = System.getProperties()
                for (e in props.propertyNames() as `java.util`.Enumeration<String>) {
                    if (e.startsWith("calcite.") || e.startsWith("avatica.")) {
                        passProperty(e)
                    }
                }
            }
            // Cannot be moved above otherwise configure each will override
            // also the specific configurations below.
            register<Test>("testSlow") {
                group = LifecycleBasePlugin.VERIFICATION_GROUP
                description = "Runs the slow unit tests."
                useJUnitPlatform() {
                    includeTags("slow")
                }
                jvmArgs("-Xmx6g")
            }
            configureEach<SpotBugsTask> {
                group = LifecycleBasePlugin.VERIFICATION_GROUP
                if (enableSpotBugs) {
                    description = "$description (skipped by default, to enable it add -Dspotbugs)"
                }
                reports {
                    html.isEnabled = reportsForHumans()
                    xml.isEnabled = !reportsForHumans()
                }
                enabled = enableSpotBugs
            }
            configureEach<JacocoReport> {
                reports {
                    // The reports are mainly consumed by Sonar, which only uses the XML format
                    xml.required.set(true)
                    html.required.set(false)
                    csv.required.set(false)
                }
            }

            afterEvaluate {
                // Add default license/notice when missing
                configureEach<Jar> {
                    CrLfSpec(LineEndings.LF).run {
                        into("META-INF") {
                            filteringCharset = "UTF-8"
                            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
                            // Note: we need "generic Apache-2.0" text without third-party items
                            // So we use the text from $rootDir/config/ since source distribution
                            // contains altered text at $rootDir/LICENSE
                            textFrom("$rootDir/src/main/config/licenses/LICENSE")
                            textFrom("$rootDir/NOTICE")
                        }
                    }
                }
            }
        }

        // Note: jars below do not normalize line endings.
        // Those jars, however are not included to source/binary distributions
        // so the normailzation is not that important

        val testJar by tasks.registering(Jar::class) {
            from(sourceSets["test"].output)
            archiveClassifier.set("tests")
        }

        val sourcesJar by tasks.registering(Jar::class) {
            from(sourceSets["main"].allJava)
            archiveClassifier.set("sources")
        }

        val javadocJar by tasks.registering(Jar::class) {
            from(tasks.named(JavaPlugin.JAVADOC_TASK_NAME))
            archiveClassifier.set("javadoc")
        }

        val archives by configurations.getting

        // Parenthesis needed to use Project#getArtifacts
        (artifacts) {
            archives(sourcesJar)
        }

        val archivesBaseName = "calcite-$name"
        setProperty("archivesBaseName", archivesBaseName)

        configure<PublishingExtension> {
            if (project.path == ":") {
                // Do not publish "root" project. Java plugin is applied here for DSL purposes only
                return@configure
            }
            if (!project.props.bool("nexus.publish", default = true)) {
                // Some of the artifacts do not need to be published
                return@configure
            }
            publications {
                create<MavenPublication>(project.name) {
                    artifactId = archivesBaseName
                    version = rootProject.version.toString()
                    description = project.description
                    from(components["java"])

                    if (!skipJavadoc) {
                        // Eager task creation is required due to
                        // https://github.com/gradle/gradle/issues/6246
                        artifact(sourcesJar.get())
                        artifact(javadocJar.get())
                    }

                    // Use the resolved versions in pom.xml
                    // Gradle might have different resolution rules, so we set the versions
                    // that were used in Gradle build/test.
                    versionMapping {
                        usage(Usage.JAVA_RUNTIME) {
                            fromResolutionResult()
                        }
                        usage(Usage.JAVA_API) {
                            fromResolutionOf("runtimeClasspath")
                        }
                    }
                    pom {
                        withXml {
                            val sb = asString()
                            var s = sb.toString()
                            // <scope>compile</scope> is Maven default, so delete it
                            s = s.replace("<scope>compile</scope>", "")
                            // Cut <dependencyManagement> because all dependencies have the resolved versions
                            s = s.replace(
                                Regex(
                                    "<dependencyManagement>.*?</dependencyManagement>",
                                    RegexOption.DOT_MATCHES_ALL
                                ),
                                ""
                            )
                            sb.setLength(0)
                            sb.append(s)
                            // Re-format the XML
                            asNode()
                        }
                        name.set(
                            (project.findProperty("artifact.name") as? String) ?: "Calcite ${project.name.capitalize()}"
                        )
                        description.set(project.description ?: "Calcite ${project.name.capitalize()}")
                        inceptionYear.set("2012")
                        url.set("https://calcite.apache.org")
                        licenses {
                            license {
                                name.set("The Apache License, Version 2.0")
                                url.set("https://www.apache.org/licenses/LICENSE-2.0.txt")
                                comments.set("A business-friendly OSS license")
                                distribution.set("repo")
                            }
                        }
                        issueManagement {
                            system.set("Jira")
                            url.set("https://issues.apache.org/jira/browse/CALCITE")
                        }
                        mailingLists {
                            mailingList {
                                name.set("Apache Calcite developers list")
                                subscribe.set("dev-subscribe@calcite.apache.org")
                                unsubscribe.set("dev-unsubscribe@calcite.apache.org")
                                post.set("dev@calcite.apache.org")
                                archive.set("https://lists.apache.org/list.html?dev@calcite.apache.org")
                            }
                        }
                        scm {
                            connection.set("scm:git:https://gitbox.apache.org/repos/asf/calcite.git")
                            developerConnection.set("scm:git:https://gitbox.apache.org/repos/asf/calcite.git")
                            url.set("https://github.com/apache/calcite")
                            tag.set("HEAD")
                        }
                    }
                }
            }
        }
    }
}
