/*
 * 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 'standard-subproject-configuration'
  id 'antlr'
  id 'geode-publish-java'
  id 'geode-pmd'
  id 'jmh'
  id 'javaVersions'
}

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
tasks.register('createVersionPropertiesFile') {
  dependsOn rootProject.tasks.named('writeBuildInfo')

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

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

  def props = [
    "Product-Name"      : productName,
    "Product-Version"   : version,
    "Build-Id"          : "${System.env.USER} ${buildId}".toString(),
    "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

  inputs.properties(props)

  doLast {
    def scmInfo = new Properties()
    new FileInputStream(scmInfoFile.singleFile).withStream { fis ->
      scmInfo.load(fis)
    }
    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)

tasks.register('raJar', Jar) {
  dependsOn tasks.named('classes')
  description 'Assembles the jar archive that contains the JCA classes'
  from sourceSets.jca.output
  exclude 'org/apache/geode/ra/**'
  archiveFileName='ra.jar'
}

tasks.register('jcaJar', Jar) {
  dependsOn tasks.named('raJar')
  description 'Assembles the jar archive that contains the JCA bundle'
  archiveBaseName='geode-jca'
  archiveExtension='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
  }

  raOutput
}

artifacts {
  raOutput raJar
}

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
  compileOnly('org.springframework:spring-web')

  // find bugs leaks in from spring, needed to remove warnings.
  compileOnly('com.google.code.findbugs:jsr305')

  compileOnly('org.jetbrains: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 validator is used to validate inet addresses in membership
  implementation('commons-validator:commons-validator')


  //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: '*'
  }

  runtimeOnly(project(':geode-deployment:geode-deployment-legacy'))

  //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
  compileOnly('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
  compileOnly('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
  compileOnly('mx4j:mx4j') {
    ext.optional = true
  }

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

  //MX4J tools is used by the old admin API
  compileOnly('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.core.v3: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'))
  api(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'))


  jcaImplementation(sourceSets.main.output)

  testImplementation(project(':geode-junit')) {
    exclude module: 'geode-core'
  }
  testImplementation(project(':geode-concurrency-test'))
  testImplementation(project(':geode-serialization'))
  testImplementation('org.apache.bcel:bcel')
  testImplementation('org.assertj:assertj-core')
  testImplementation('org.mockito:mockito-core')
  testImplementation('org.mockito:mockito-junit-jupiter')
  testImplementation('com.pholser:junit-quickcheck-core')
  testImplementation('pl.pragmatists:JUnitParams')
  testImplementation('com.tngtech.archunit:archunit-junit4')
  testImplementation(project(path: ':geode-core', configuration: 'raOutput'))
  testImplementation('org.springframework:spring-web')
  testImplementation(files("${System.getProperty('java.home')}/../lib/tools.jar"))
  testImplementation('org.junit-pioneer:junit-pioneer')

  testCompileOnly('org.jetbrains:annotations')

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

  // Needed for JDK8, not JDK11, after nebula.facet v7.0.9
  integrationTestImplementation(files("${System.getProperty('java.home')}/../lib/tools.jar"))
  integrationTestImplementation(project(':geode-gfsh'))
  integrationTestImplementation(project(':geode-junit'))
  integrationTestImplementation(project(':geode-dunit'))
  integrationTestImplementation(project(':geode-log4j'))
  integrationTestImplementation(project(':geode-concurrency-test'))
  integrationTestImplementation(project(':geode-serialization'))
  integrationTestImplementation('org.apache.bcel:bcel')
  integrationTestImplementation('org.apache.logging.log4j:log4j-core')
  integrationTestImplementation('pl.pragmatists:JUnitParams')
  integrationTestImplementation('com.tngtech.archunit:archunit-junit4')
  integrationTestImplementation('org.junit-pioneer:junit-pioneer')

  integrationTestRuntimeOnly('org.apache.derby:derby')
  integrationTestRuntimeOnly('xerces:xercesImpl')
  integrationTestRuntimeOnly('com.fasterxml.jackson.datatype:jackson-datatype-jsr310')

  // The block below is only for the deprecated admin mbeans API
  integrationTestRuntimeOnly('commons-modeler:commons-modeler')
  integrationTestRuntimeOnly('org.springframework:spring-web')
  integrationTestRuntimeOnly('javax.mail:javax.mail-api')
  integrationTestRuntimeOnly('mx4j:mx4j')
  integrationTestRuntimeOnly('mx4j:mx4j-remote')
  integrationTestRuntimeOnly('mx4j:mx4j-tools')
  // End deprecated requirements


  distributedTestImplementation(project(':geode-gfsh'))
  distributedTestImplementation(project(':geode-wan'))
  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')

  distributedTestRuntimeOnly('org.apache.derby:derby')


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

  upgradeTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'classpathsOutput'))
  upgradeTestRuntimeOnly(project(':geode-log4j'))
  upgradeTestRuntimeOnly(project(':geode-old-client-support'))

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

  jmhImplementation('org.jctools:jctools-core')
}

tasks.eclipse.dependsOn(generateGrammarSource)

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

configure([
  upgradeTest,
  repeatUpgradeTest
]) {
  dependsOn(':geode-assembly:installDist')

  environment "JAVA_HOME_8u265", javaHomeForVersion(it, "jdk8u265", "8u265+1")
  environment "JAVA_HOME_8u272", javaHomeForVersion(it, "jdk8u272", "8u272+10")
  environment 'GEODE_HOME', "$buildDir/../../geode-assembly/build/install/apache-geode"
}

rootProject.generate.dependsOn(generateGrammarSource)
