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

plugins {
    id 'me.champeau.gradle.jmh' version '0.4.8'
}

apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"

apply plugin: 'antlr'
apply from: "${project.projectDir}/../gradle/publish-java.gradle"
apply from: "${project.projectDir}/../gradle/pmd.gradle"

sourceSets {
    jca {
        compileClasspath += configurations.compileClasspath
        runtimeClasspath += configurations.runtimeClasspath
    }
}

idea {
    module {
        testSourceDirs += project.tasks.generateIntegrationTestGrammarSource.outputs.files
        testSourceDirs += project.tasks.generateDistributedTestGrammarSource.outputs.files
        testSourceDirs += project.tasks.generatePerformanceTestGrammarSource.outputs.files
        testSourceDirs += project.tasks.generateUpgradeTestGrammarSource.outputs.files
    }
}

def generatedResources = "$buildDir/generated-resources/main"

sourceSets {
    main {
        output.dir(generatedResources, builtBy: 'createVersionPropertiesFile')
    }
    test {
        output.dir(generatedResources, builtBy: 'createVersionPropertiesFile')
    }
}

sourceSets {
// This works around resource-look up between integrationTest and test source-sets.
// See GEODE-5803 / GEODE-5882
    test.resources.srcDirs.each { testResourceSrc ->
        integrationTest.resources.srcDir {
            testResourceSrc
        }
    }
}


// Creates the version properties file and writes it to the classes dir
task createVersionPropertiesFile(dependsOn: ':writeBuildInfo') {

    def propertiesFile = file(generatedResources + "/org/apache/geode/internal/GemFireVersion.properties")
    def scmInfoFile = rootProject.tasks.writeBuildInfo.outputs.files

    inputs.files {
        scmInfoFile
    }
    outputs.files {
        propertiesFile
    }


    doLast {
        def scmInfo = new Properties()
        new FileInputStream(scmInfoFile.singleFile).withStream { fis ->
            scmInfo.load(fis)
        }

        def props = [
                "Product-Name"      : productName,
                "Product-Version"   : version,
                "Build-Id"          : "${System.env.USER} ${buildId}".toString(),
                "Build-Date"        : new Date().format('yyyy-MM-dd HH:mm:ss Z'),
                "Build-Platform"    : "${System.properties['os.name']} ${System.properties['os.version']} ${System.properties['os.arch']}".toString(),
                "Build-Java-Vendor" : System.properties['java.vendor'],
                "Build-Java-Version": System.properties['java.version']
        ] as Properties
        props.putAll(scmInfo)

        propertiesFile.getParentFile().mkdirs()
        new FileOutputStream(propertiesFile).withStream { fos ->
            props.store(fos, '')
        }
    }
}

ext.moduleName = group + '.core'

jar {

    from sourceSets.main.output
    from sourceSets.jca.output

    exclude 'org/apache/geode/internal/i18n/StringIdResourceBundle_ja.txt'
    exclude 'org/apache/geode/admin/doc-files/ds4_0.dtd'

    inputs.property("moduleName", moduleName)
    manifest {
        attributes('Automatic-Module-Name': moduleName)
    }

}

jar.dependsOn(createVersionPropertiesFile)

upgradeTest {
  environment 'GEODE_HOME', "$buildDir/../../geode-assembly/build/install/apache-geode/"
}

repeatUpgradeTest {
  environment 'GEODE_HOME', "$buildDir/../../geode-assembly/build/install/apache-geode/"
}

task raJar(type: Jar, dependsOn: classes) {
    description 'Assembles the jar archive that contains the JCA classes'
    from sourceSets.jca.output
    exclude 'org/apache/geode/ra/**'
    archiveName 'ra.jar'
}

task jcaJar(type: Jar, dependsOn: raJar) {
    description 'Assembles the jar archive that contains the JCA bundle'
    baseName 'geode-jca'
    extension 'rar'
    metaInf { from 'src/jca/ra.xml' }
    from raJar.archivePath
}

configurations {
    //declaring new configuration that will be used to associate with artifacts
    archives

    classesOutput {
        extendsFrom api
        description 'a dependency that exposes the compiled classes'
    }

    jmh {
        extendsFrom testImplementation
    }
}

dependencies {

    //These bom dependencies are used to constrain the versions of the dependencies listed below
    api(platform(project(':boms:geode-all-bom')))
    compileOnly(platform(project(':boms:geode-all-bom')))
    testCompileOnly(platform(project(':boms:geode-all-bom')))
    // As plugin configurations that do not extend from compile,
    // we must explicitly impose version constraints on these configurations.
    antlr platform(project(':boms:geode-all-bom'))
    jcaAnnotationProcessor(platform(project(':boms:geode-all-bom')))

    //A dependency that contains the compiled output of the source. What is this for?
    classesOutput sourceSets.main.output


    // Source Dependencies
    //------------------------------------------------------------

    //  The antlr configuration is used by the antlr plugin, which compiles grammar
    // files used by the query engine
    antlr 'antlr:antlr'

    // External
    //------------------------------------------------------------

    //Commons IO is used in persistence and management
    api('commons-io:commons-io')

    //tools.jar seems to be used by gfsh is some cases to control processes using
    //the sun attach API? But this code path may not even be used?
    compileOnly(files("${System.getProperty('java.home')}/../lib/tools.jar"))

    //Find bugs is used in multiple places in the code to suppress findbugs warnings
    compileOnly('com.github.stephenc.findbugs:findbugs-annotations')
    testCompileOnly('com.github.stephenc.findbugs:findbugs-annotations')

    //Spring web is used for SerializableObjectHttpMessageConverter
    implementation('org.springframework:spring-web')
    // find bugs leaks in from spring, needed to remove warnings.
    compileOnly('com.google.code.findbugs:jsr305')

    //Jgroups is a core component of our membership system.
    implementation('org.jgroups:jgroups')

    //Antlr is used by the query engine.
    implementation('antlr:antlr')

    //Jackson annotations is used in gfsh
    implementation('com.fasterxml.jackson.core:jackson-annotations')

    //Jackson databind is used in gfsh, and also in pdx
    implementation('com.fasterxml.jackson.core:jackson-databind')

    //Commons validator is used to validate inet addresses in membership
    implementation('commons-validator:commons-validator')

    //javax.activation is runtime dependency for gfsh with java 11 (used by gfsh-over-http)
    runtimeOnly('com.sun.activation:javax.activation')

    //jaxb is used by cluster configuration
    implementation('javax.xml.bind:jaxb-api')

    //jaxb is used by cluster configuration
    implementation('com.sun.xml.bind:jaxb-impl')

    //istack appears to be used only by jaxb, not in our code. jaxb doesn't
    //declare this as required dependency though. It's unclear if this is needed
    //Runtime
    runtimeOnly('com.sun.istack:istack-commons-runtime') {
        exclude group: '*'
    }

    //Commons lang is used in many different places in core
    implementation('org.apache.commons:commons-lang3')

    //Commons modeler is used by the (deprecated) admin API
    implementation('commons-modeler:commons-modeler') {
        exclude module: 'commons-logging-api'
        exclude module: 'mx4j-jmx'
        exclude module: 'xml-apis'
        ext.optional = true
    }

    //micrometer is used for micrometer based metrics from geode geode
    api('io.micrometer:micrometer-core')


    //FastUtil contains optimized collections that are used in multiple places in core
    implementation('it.unimi.dsi:fastutil')

    //Mail API is used by the deprecated admin API
    implementation('javax.mail:javax.mail-api') {
        ext.optional = true
    }

    //The resource-API is used by the JCA support.
    api('javax.resource:javax.resource-api')


    //MX4J is used by the old admin API
    implementation('mx4j:mx4j') {
        ext.optional = true
    }

    //MX4J remote is used by the old admin API
    implementation('mx4j:mx4j-remote') {
        ext.optional = true
    }

    //MX4J tools is used by the old admin API
    implementation('mx4j:mx4j-tools') {
        ext.optional = true
    }

    //JNA is used for locking memory and preallocating disk files.
    implementation('net.java.dev.jna:jna')
    implementation('net.java.dev.jna:jna-platform')

    //JOptSimple is used by gfsh. A couple of usages have leaked into DiskStore
    implementation('net.sf.jopt-simple:jopt-simple')

    //Log4j is used everywhere
    implementation('org.apache.logging.log4j:log4j-api')


    implementation('io.swagger:swagger-annotations') {
        ext.optional = true
    }

    runtimeOnly(project(':geode-http-service')) {
        ext.optional = true
    }

    //Snappy is used for compressing values, if enabled
    implementation('org.iq80.snappy:snappy') {
        ext.optional = true
    }

    //Shiro is used for security checks throughout geode-core
    //API - Shiro is exposed in geode's ResourcePermission class
    api('org.apache.shiro:shiro-core')

    //Classgraph is used by the gfsh cli, and also for function deployment (which happens in a server
    //in response to a gfsh command)
    implementation('io.github.classgraph:classgraph')

    //RMIIO is used for uploading jar files and copying them between locator an servers
    implementation('com.healthmarketscience.rmiio:rmiio')

    //Geode-common has annotations and other pieces used geode-core
    api(project(':geode-common'))
    implementation(project(':geode-logging'))
    implementation(project(':geode-membership'))
    implementation(project(':geode-unsafe'))
    implementation(project(':geode-serialization'))
    implementation(project(':geode-tcp-server'))

    //geode-management currently has pieces of the public API
    //copied into it, so it is an API dependency
    api(project(':geode-management'))


    jcaCompile(sourceSets.main.output)

    testImplementation(project(':geode-junit')) {
        exclude module: 'geode-core'
    }
    testImplementation(project(':geode-concurrency-test'))
    testImplementation('org.apache.bcel:bcel')
    testImplementation('org.assertj:assertj-core')
    testImplementation('org.mockito:mockito-core')
    testImplementation('com.pholser:junit-quickcheck-core')
    testImplementation('org.powermock:powermock-core')
    testImplementation('org.powermock:powermock-module-junit4')
    testImplementation('org.powermock:powermock-api-mockito2')
    testImplementation('pl.pragmatists:JUnitParams')
    testImplementation('com.tngtech.archunit:archunit-junit4')

    testImplementation(files("${System.getProperty('java.home')}/../lib/tools.jar"))

    testRuntime('commons-collections:commons-collections')
    testRuntime('commons-configuration:commons-configuration')
    testRuntime('commons-io:commons-io')
    testRuntime('commons-validator:commons-validator')
    testRuntime('com.pholser:junit-quickcheck-generators')

    integrationTestImplementation(project(':geode-gfsh'))
    integrationTestImplementation(project(':geode-junit')) {
        exclude module: 'geode-core'
    }
    integrationTestImplementation(project(':geode-dunit')) {
        exclude module: 'geode-core'
    }
    integrationTestImplementation(project(':geode-log4j')) {
        exclude module: 'geode-core'
    }
    integrationTestImplementation(project(':geode-concurrency-test'))
    integrationTestImplementation('org.apache.bcel:bcel')
    integrationTestImplementation('org.apache.logging.log4j:log4j-core')
    integrationTestImplementation('org.powermock:powermock-core')
    integrationTestImplementation('org.powermock:powermock-module-junit4')
    integrationTestImplementation('org.powermock:powermock-api-mockito2')
    integrationTestImplementation('pl.pragmatists:JUnitParams')
    integrationTestImplementation('com.tngtech.archunit:archunit-junit4')

    integrationTestRuntime(project(path: ':geode-old-versions', configuration: 'testOutput'))

    integrationTestRuntimeOnly('org.apache.derby:derby')
    integrationTestRuntimeOnly('xerces:xercesImpl')

    distributedTestImplementation(project(':geode-gfsh'))
    distributedTestImplementation(project(':geode-junit')) {
        exclude module: 'geode-core'
    }
    distributedTestImplementation(project(':geode-dunit')) {
        exclude module: 'geode-core'
    }
    distributedTestImplementation(project(':geode-log4j')) {
        exclude module: 'geode-core'
    }
    distributedTestImplementation('pl.pragmatists:JUnitParams')
    distributedTestImplementation('com.jayway.jsonpath:json-path-assert')
    distributedTestImplementation('net.openhft:compiler')

    distributedTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
    distributedTestRuntimeOnly('org.apache.derby:derby')


    upgradeTestImplementation(project(':geode-dunit')) {
        exclude module: 'geode-core'
    }

    upgradeTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
    upgradeTestRuntimeOnly(project(':geode-log4j'))


    performanceTestImplementation(project(':geode-junit')) {
        exclude module: 'geode-core'
    }
    performanceTestImplementation(project(':geode-log4j'))
}

jmh {
    duplicateClassesStrategy = 'warn'
    include = project.hasProperty('jmh.include') ? project.getProperties().get('jmh.include') : '.*'
    profilers = project.hasProperty('jmh.profilers') ? project.getProperties().get('jmh.profilers').tokenize() : []
    threads = project.hasProperty('jmh.threads') ? project.getProperties().get('jmh.threads') : null
}

jmhJar {
    inputs.files(project.sourceSets.main.output, project.sourceSets.test.output)
    from {
        [configurations.jmh, configurations.jmhRuntime, configurations.runtimeClasspath].collect {
            it.asFileTree.collect {
                it
            }
        }.flatten().unique().collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    exclude(['META-INF/*.SF'])
    exclude('META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat')
    exclude('*.jar')
}

tasks.eclipse.dependsOn(generateGrammarSource)

distributedTest {
    // Some tests have inner tests that should be ignored
    exclude "**/*\$*.class"
}

rootProject.generate.dependsOn(generateGrammarSource)
