/*
 * fdb-relational-cli.gradle
 *
 * This source file is part of the FoundationDB open source project
 *
 * Copyright 2015-2024 Apple Inc. and the FoundationDB project authors
 *
 * Licensed 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.
 */

plugins {
    id 'application'
    alias(libs.plugins.shadow)
}

apply from: rootProject.file('gradle/publishing.gradle')
apply from: rootProject.file('gradle/antlr.gradle')

// Don't build a zip assembly, just the tar one.
tasks.distZip.enabled = false
build.dependsOn installDist

def coreProject = ":${ext.coreProjectName}"
dependencies {
    // TODO: Some of these dependencies are probably unnecessary as they were added when there was more
    //  logic in the CLI package that is no longer included

    implementation project(":fdb-relational-api")
    implementation project(":fdb-relational-core")
    implementation project(":fdb-relational-grpc")
    // This module depends on jdbc and server. It is not 'pure' like the
    // fdb-relational-jdbc module that wants no server/core pollution.
    implementation project(":fdb-relational-server")
    implementation project(":fdb-relational-jdbc")
    implementation project(":fdb-record-layer-debugger")
    implementation project(coreProject)
    // we currently pack the Cascades debugger in this package, maybe in the future we should
    // move it to a more appropriate package such as utils or something similar so we can
    // consume it from there.
    implementation project(path: coreProject, configuration: 'tests')
    implementation(libs.dropwizard) {
        exclude group: 'org.slf4j'
    }
    implementation(libs.asciitable) {
        exclude group: 'org.slf4j'
    }
    implementation(libs.sqlline)
    implementation(libs.protobuf.util)

    compileOnly(libs.autoService)
    annotationProcessor(libs.autoService)

    // See diagram on this page: https://logging.apache.org/log4j/2.x/faq.html#which_jars
    implementation(libs.log4j.api)
    // slf4j binding. Allows RL dependencies to log to same place as Relational
    runtimeOnly(libs.log4j.slf4jBinding)
    runtimeOnly(libs.log4j.julBinding)
    runtimeOnly(libs.log4j.core)

    testImplementation(libs.bundles.test.impl)
    testRuntimeOnly(libs.bundles.test.runtime)
    testCompileOnly(libs.bundles.test.compileOnly)
    testImplementation(libs.apache.commonsCollections)

    antlr(libs.antlr)
}

def mainCliClass = 'com.apple.foundationdb.relational.cli.sqlline.RelationalSQLLine'

jar {
    manifest {
        attributes(
                'Main-Class': mainCliClass,
                'Class-Path': 'catalog.jar'
        )
    }
}

shadowJar {
    application {
        mainClass = mainCliClass
    }
    mergeServiceFiles()
}

build.dependsOn(shadowJar)

tasks.withType(Jar) { task ->
    dependsOn(tasks.withType(AntlrTask))
}

def relationalCorePath=rootProject.childProjects['fdb-relational-core'].projectDir.path+'/src/main/antlr'
generateGrammarSource {
    arguments += ['-lib', relationalCorePath]
}

application {
    // https://docs.gradle.org/current/userguide/application_plugin.html
    // https://github.com/julianhyde/sqlline
    mainClass = "com.apple.foundationdb.relational.cli.sqlline.RelationalSQLLine"
    applicationName = "fdb-relational-sqlline"
    // JUL => log4j2 https://logging.apache.org/log4j/2.x/log4j-jul/index.html
    // TODO: Allow overriding default fdb.cluster file with FDB_CLUSTER_FILE.

    // The gradle application defaultJvmOpts and applicationDefaultJvmArgs don't work if
    // you try to pass more than one -D option and/or you want to use a variable from
    // surrounding script. The value of the DEFAULT_JVM_OPTS has weird quoting that can't
    // be worked around and that prevents environment variable interpolation working.
    // So, we do the below crass substitution. It sets log4j as our log manager and it
    // points at log4j2.xml in the `conf` dir copied from `src/main/conf` on assembly.
    // We need to point at an explicit log configuration file because there are a bunch on
    // the CLASSPATH as it is with recordlayer stealing the pole position by bundling a
    // `log4j2-test.properties` in its jar which log4j2 will favor over all others (this
    // configuration sets the root logger to be DEBUG which spews loads of unrelated stuff
    // on the console when shell is trying to start up).
    var jvmOps =  'DEFAULT_JVM_OPTS=\"-Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager -Dlog4j2.configurationFile=file:$APP_HOME/conf/log4j2.xml\"'
    startScripts {
        doLast {
            unixScript.text = unixScript.text.replace('DEFAULT_JVM_OPTS=\"\"', jvmOps)
        }
    }

    startShadowScripts {
        doLast {
            unixScript.text = unixScript.text.replace('DEFAULT_JVM_OPTS=\"\"', jvmOps)
        }
    }
}

distTar {
    dependsOn javadoc
    dependsOn shadowJar
    compression = Compression.GZIP
    archiveExtension = "tar.gz"
}

createDistribution.configure {
    afterEvaluate {
        dependsOn shadowJar
        from tasks.shadowJar
    }
}

publishing {
    publications {
        library(MavenPublication) {
            pom {
                description = 'Relational CLI (Connects to FDB Relational Layer via JDBC)'
            }
        }
    }
}
