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

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

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


  //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
  implementation('com.github.stephenc.findbugs:findbugs-annotations')

  //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 IO is used in persistence and management
  implementation('commons-io:commons-io')

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

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

  //Jansi is used by the CLI (maybe? it is a runtime dependency)
  runtimeOnly('org.fusesource.jansi:jansi') {
    ext.optional = true
  }

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

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

  //Spring core is used by the the gfsh cli
  implementation('org.springframework:spring-core') {
    ext.optional = true
  }

  //Spring shell is used by the gfsh cli. It's unclear why we can exclude
  //So many transitive dependencies - are these really optional?
  //GfshCommand is a public API class that depends on spring shell
  api('org.springframework.shell:spring-shell') {
    exclude module: 'aopalliance'
    exclude module: 'asm'
    exclude module: 'cglib'
    exclude module: 'guava'
    exclude module: 'spring-aop'
    exclude module: 'spring-context-support'
    exclude module: 'spring-core'
  }

  //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-unsafe'))
  implementation(project(':geode-serialization'))

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

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

  testCompile 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')
  testRuntime(project(path: ':geode-old-versions', configuration: 'testOutput'))


  integrationTestCompile(project(':geode-junit')) {
    exclude module: 'geode-core'
  }
  integrationTestCompile(project(':geode-dunit')) {
    exclude module: 'geode-core'
  }
  integrationTestImplementation(project(':geode-log4j')) {
    exclude module: 'geode-core'
  }
  integrationTestCompile(project(':geode-concurrency-test'))
  integrationTestCompile('org.apache.bcel:bcel')
  integrationTestCompile('org.powermock:powermock-core')
  integrationTestCompile('org.powermock:powermock-module-junit4')
  integrationTestCompile('org.powermock:powermock-api-mockito2')
  integrationTestCompile('org.springframework:spring-test')
  integrationTestCompile('pl.pragmatists:JUnitParams')

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


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

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


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

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


  performanceTestCompile(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)
