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

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

import org.apache.geode.gradle.plugins.DependencyConstraints
import org.apache.tools.ant.taskdefs.condition.Os

import java.nio.file.Paths

// This project aggressively reaches into many other projects and must wait for those configurations
// to be evaluated and resolved.  Evaluation depends on each of these subprojects.

// This list is used in a loop to defined the /lib copySpec
def dependentProjectNames = [
  ':geode-common',
  ':geode-connectors',
  ':geode-core',
  ':geode-cq',
  ':geode-gfsh',
  ':geode-log4j',
  ':geode-logging',
  ':geode-lucene',
  ':geode-memcached',
  ':geode-old-client-support',
  ':geode-protobuf',
  ':geode-protobuf-messages',
  ':geode-rebalancer',
  ':geode-redis',
  ':geode-serialization',
  ':geode-tcp-server',
  ':geode-wan'
]

// These other dependencies are explicitly referenced throughout other copySpec
def otherDependentProjectNames = [
  ':extensions:geode-modules',
  ':extensions:geode-modules-assembly',
  ':extensions:geode-modules-session',
  ':extensions:geode-modules-session',
  ':extensions:geode-modules-tomcat7',
  ':extensions:geode-modules-tomcat8',
  ':extensions:geode-modules-tomcat9',
  ':geode-experimental-driver',
  ':geode-management',
  ':geode-pulse',
  ':geode-web',
  ':geode-web-api',
  ':geode-web-management',
]

evaluationDependsOnChildren()
(dependentProjectNames + otherDependentProjectNames).each { neighborProjectName ->
  project.evaluationDependsOn(neighborProjectName)
}

apply plugin: 'distribution'
apply plugin: 'com.palantir.docker'
apply from: "${rootDir}/${scriptDir}/publish-common.gradle"


// This subproject's 'publication' is not a jar and should not be constrained to match versions
// in the geode-all-bom.
project.ext.set('constrainVersionInBom', false)

project.ext {artifactName = 'apache-geode'}

configurations {
  compositeTarget {
    setDescription("Composite builds wishing to consume this apache-geode@tgz artifact must specify \"targetConfiguration = 'compositeTarget'\" for correct composite task dependency detection.")
  }

  gfshDependencies

  // Configurations used to download and cache web application servers for session module testing
  webServerTomcat6
  webServerTomcat7
  webServerTomcat8
  webServerTomcat9
  webServerJetty

  geodeArchives {
    setDescription("An 'archives' configuration without the legacy publication implications")
  }

  javadocOnly {
    setDescription('Projects that must be included in the JavaDocs.')
    extendsFrom geodeArchives
  }
}

publishing {
  publications {
    maven(MavenPublication) {
      artifactId = artifactName
      artifact source: distTar, extension: 'tgz'
    }
  }
}

gradle.taskGraph.whenReady( { graph ->
  tasks.withType(AbstractArchiveTask).findAll {
    it.name.toLowerCase().contains("dist")
  }.each { archive ->
    archive.doLast {
      ant.checksum file:"${archive.archivePath}", algorithm:"sha-256", format: 'MD5SUM', fileext: '.sha256'
    }
  }
})

artifacts {
  compositeTarget distTar
}

//This "repository" only exists to download tomcat-6, because the zip for tomcat 6 is
//not in a maven repo. Later versions of tomcat are.
repositories {
  ivy {
    url 'https://archive.apache.org/'
    patternLayout {
      artifact '/dist/tomcat/tomcat-6/v6.0.37/bin/[organisation]-[module]-[revision].[ext]'
    }
  }
  // For gradle tooling dependencies
  maven {
    url 'https://repo.gradle.org/gradle/libs-releases'
  }
  // docker-compose-rule is published on bintray
  maven {
    url 'https://dl.bintray.com/palantir/releases'
  }
}

def webServersDir = "$buildDir/generated-resources/webservers"

sourceSets {
  distributedTest {
    resources {
      srcDirs webServersDir
    }
    output.dir(webServersDir, builtBy: 'downloadWebServers')
  }
}

task downloadWebServers(type:Copy) {
  from {configurations.findAll {it.name.startsWith("webServer")}}
  into webServersDir
}

dependencies {
  compile(platform(project(':boms:geode-all-bom')))
  gfshDependencies(platform(project(':boms:geode-all-bom')))

  dependentProjectNames.each {
    geodeArchives(project(it))
  }
  geodeArchives project(':geode-management')
  geodeArchives project(path: ':geode-web', configuration: 'war')
  geodeArchives project(path: ':geode-web-api', configuration: 'war')
  geodeArchives project(path: ':geode-web-management', configuration: 'war')

  javadocOnly project(':extensions:geode-modules')
  javadocOnly project(':extensions:geode-modules-session')
  javadocOnly project(':extensions:geode-modules-session')
  javadocOnly project(':extensions:geode-modules-tomcat7')
  javadocOnly project(':extensions:geode-modules-tomcat9')
  javadocOnly project(':extensions:geode-modules-tomcat8')
  javadocOnly project(':geode-experimental-driver')

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

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

  integrationTestImplementation(project(':geode-core'))
  integrationTestImplementation(project(':geode-gfsh'))
  integrationTestImplementation(project(':geode-log4j')) {
    exclude module: 'geode-core'
  }
  integrationTestImplementation(project(':geode-junit')) {
    exclude module: 'geode-core'
  }
  integrationTestImplementation(project(':geode-dunit')) {
    exclude module: 'geode-core'
  }
  integrationTestImplementation(project(':geode-pulse'))
  integrationTestImplementation(project(':geode-assembly:geode-assembly-test'))
  integrationTestImplementation(project(':geode-logging'))
  integrationTestImplementation('org.apache.httpcomponents:httpclient')
  integrationTestImplementation('org.springframework:spring-beans')
  integrationTestImplementation('org.springframework:spring-context')
  integrationTestImplementation('org.springframework:spring-web')
  integrationTestImplementation('org.springframework.security:spring-security-oauth2-core')
  integrationTestImplementation('org.springframework.security:spring-security-oauth2-client')
  integrationTestImplementation('org.springframework.security:spring-security-oauth2-jose')
  integrationTestImplementation('javax.annotation:javax.annotation-api')
  integrationTestImplementation('javax.servlet:javax.servlet-api')

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

  integrationTestRuntimeOnly('io.swagger:swagger-annotations')
  // these two modules are for testing only
  integrationTestRuntimeOnly('com.fasterxml.jackson.datatype:jackson-datatype-joda')
  integrationTestRuntimeOnly('joda-time:joda-time')

  distributedTestCompileOnly(platform(project(':boms:geode-all-bom')))
  distributedTestCompileOnly('io.swagger:swagger-annotations')
  distributedTestImplementation(project(':geode-gfsh'))
  distributedTestImplementation(project(':geode-logging'))
  distributedTestImplementation(project(':geode-membership'))
  distributedTestImplementation(project(':geode-serialization'))
  distributedTestImplementation(project(':geode-tcp-server'))
  distributedTestImplementation(project(':geode-core'))
  distributedTestImplementation(project(':geode-log4j')) {
    exclude module: 'geode-core'
  }
  distributedTestImplementation(project(':geode-dunit')){
    exclude module: 'geode-core'
  }
  distributedTestImplementation(project(':extensions:session-testing-war'))
  distributedTestImplementation(project(':geode-assembly:geode-assembly-test'))
  distributedTestImplementation('org.apache.httpcomponents:httpclient')
  distributedTestImplementation('org.springframework:spring-web')
  distributedTestImplementation(project(':geode-management'))
  distributedTestImplementation(project(':geode-web-management'))
  distributedTestImplementation('com.arakelian:java-jq')
  distributedTestImplementation('javax.servlet:javax.servlet-api')

  distributedTestRuntimeOnly(project(':extensions:geode-modules-session-internal')) {
    exclude group: 'org.apache.tomcat'
  }
  distributedTestRuntimeOnly('org.codehaus.cargo:cargo-core-uberjar')
  distributedTestRuntimeOnly('io.swagger:swagger-annotations')
  distributedTestRuntimeOnly(project(':geode-wan'))

  // geodeArchives is a direct reflection of what is contained in geode-dependencies.jar. To that
  // end only add _test_ dependencies to acceptanceTestCompile/Runtime. All other product
  // dependencies should be a part of geodeArchives and should not need to be added as individual
  // dependencies here.
  acceptanceTestImplementation(configurations.geodeArchives)
  acceptanceTestImplementation(project(':geode-dunit')) {
    exclude module: 'geode-core'
  }
  acceptanceTestImplementation(project(':geode-assembly:geode-assembly-test'))

  // This is used by 'gradle within gradle' tests. No need to bump this version; but if you do,
  // don't have it be the same version as the outer gradle version.
  acceptanceTestImplementation('org.gradle:gradle-tooling-api:5.1.1')

  acceptanceTestImplementation('com.palantir.docker.compose:docker-compose-rule-core')
  acceptanceTestImplementation('com.palantir.docker.compose:docker-compose-rule-junit4')

  uiTestImplementation(project(':geode-core'))
  uiTestImplementation(project(':geode-dunit')) {
    exclude module: 'geode-core'
  }
  uiTestImplementation(project(':geode-pulse'))
  uiTestImplementation(project(':geode-pulse:geode-pulse-test'))
  uiTestImplementation(project(':geode-assembly:geode-assembly-test'))
  uiTestImplementation('org.seleniumhq.selenium:selenium-api')
  uiTestImplementation('org.seleniumhq.selenium:selenium-remote-driver')
  uiTestImplementation('org.seleniumhq.selenium:selenium-support')

  uiTestRuntimeOnly(project(':geode-core'))
  uiTestRuntimeOnly('org.seleniumhq.selenium:selenium-chrome-driver')

  upgradeTestImplementation(project(':geode-gfsh'))
  upgradeTestImplementation(project(':geode-logging'))
  upgradeTestImplementation(project(':geode-serialization'))
  upgradeTestImplementation(project(':geode-core'))
  upgradeTestImplementation(project(':geode-dunit')) {
    exclude module: 'geode-core'
  }
  upgradeTestImplementation(project(':geode-assembly:geode-assembly-test'))

  upgradeTestCompileOnly(platform(project(':boms:geode-all-bom')))
  upgradeTestCompileOnly('io.swagger:swagger-annotations')

  upgradeTestRuntimeOnly(project(path: ':geode-old-versions', configuration: 'testOutput'))
  upgradeTestRuntimeOnly(project(':extensions:session-testing-war'))
  upgradeTestRuntimeOnly('org.codehaus.cargo:cargo-core-uberjar')
  upgradeTestRuntimeOnly('org.apache.httpcomponents:httpclient')
  upgradeTestRuntime files({ downloadWebServers } )

  //Web servers used for session module testing
  webServerTomcat6('apache:tomcat:' + DependencyConstraints.get('tomcat6.version') + '@zip')
  webServerTomcat7('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat7.version') + '@zip')
  webServerTomcat8('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat8.version') + '@zip')
  webServerTomcat9('org.apache.tomcat:tomcat:' + DependencyConstraints.get('tomcat9.version') + '@zip')
  webServerJetty('org.eclipse.jetty:jetty-distribution:' + DependencyConstraints.get('jetty.version') + '@zip')

  gfshDependencies ('org.springframework:spring-web') {
    exclude module: 'spring-core'
    exclude module: 'commons-logging'
  }
}

acceptanceTest {
    // This is specifically used by GradleBuildWithGeodeCoreAcceptanceTest
    systemProperty 'projectGroup', project.group
}

tasks.register('defaultDistributionConfig', JavaExec) {
  inputs.files {
    project(':geode-core').sourceSets.main.runtimeClasspath
  }
  outputs.file file("$buildDir/gemfire.properties")
  main 'org.apache.geode.distributed.internal.DefaultPropertiesGenerator'
  classpath project(':geode-core').sourceSets.main.runtimeClasspath
  workingDir buildDir

  doFirst {
    buildDir.mkdirs()
  }
}

tasks.register('defaultCacheConfig', JavaExec) {
  inputs.files {
    project(':geode-core').sourceSets.main.runtimeClasspath
  }
  outputs.file file("$buildDir/cache.xml")
  main 'org.apache.geode.internal.cache.xmlcache.CacheXmlGenerator'
  classpath project(':geode-core').sourceSets.main.runtimeClasspath
  workingDir buildDir

  doFirst {
    buildDir.mkdirs()
  }
}

// This closure sets the geode classpath.  If we add another jar to the classpath it must
// be included in the filter logic below.
def cp = {
  // first add all the dependent project jars
  def jars = configurations.geodeArchives.dependencies.collect { it.dependencyProject }
    .findAll { !(it.name.contains('geode-web') || it.name.contains('geode-pulse')) }
    .collect { it.jar.archiveName }

  // then add all the dependencies of the dependent jars
  def depJars = configurations.geodeArchives.dependencies.collect {
    it.dependencyProject.findAll {
      !(it.name.contains('geode-web') ||
        it.name.contains('geode-pulse'))
    }.collect {
      it.configurations.runtimeClasspath.collect { it.getName() }.findAll { !(
          it.contains('geode-all-bom') ||

            // exclude mx4j, once the deprecated code is deleted we can remove these entirely
            it.contains('commons-digester') ||
            it.contains('commons-modeler') ||
            it.contains('javax.mail-api') ||
            it.contains('mx4j') ||

            // misc jars, these should be removed from the lib dir
            it.contains('findbugs-annotations') ||
            it.contains('geode-dependencies') ||
            it.contains('geode-jca') ||
            it.contains('geode-web') ||
            it.contains('gfsh-dependencies') ||
            it.contains('ra.jar') ||

            // spring web deps that shouldn't be here either
            it.contains('spring-aop') ||
            it.contains('spring-beans') ||
            it.contains('spring-context') ||
            it.contains('spring-expression') ||
            it.contains('spring-web')
        )}
    }
  }.flatten()

  return jars.plus(depJars).unique().join(' ')
}

tasks.register('configureDepsJar') {
  inputs.files {
    configurations.geodeArchives
  }

  def output = project.buildDir.toPath().resolve('reports').resolve('deps_jar_cp.txt')
  outputs.file {
    output
  }
  doLast {
    output.write(cp())
  }
}

tasks.register('configureGfshDepsJar') {
  inputs.files {
    configurations.gfshDependencies
  }

  inputs.files {
    configureDepsJar
  }

  def output = project.buildDir.toPath().resolve('reports').resolve('gfsh_deps_jar_cp.txt')
  outputs.file {
    output
  }
  doLast {
    def classpath = configureDepsJar.outputs.files.singleFile.text + ' ' +
        configurations.gfshDependencies.collect { it.getName() }.findAll {
          !it.contains('geode-all-bom')
        }.flatten().unique().join(' ')
    output.write(classpath)
  }
}

// Configure the manifest contents in a separate always-running task to ensure correctness of
// these dependency jars
tasks.register('depsJar', Jar) {
  inputs.files {
    configureDepsJar
  }
  description 'Assembles the jar archive that defines the gemfire classpath.'
  archiveName 'geode-dependencies.jar'
  doFirst {
    manifest {
      attributes("Class-Path": configureDepsJar.outputs.files.singleFile.text)
    }
  }
}

tasks.register('gfshDepsJar', Jar) {
  inputs.files {
    configureGfshDepsJar
  }
  description 'Assembles the jar archive that defines the gfsh classpath.'
  archiveName 'gfsh-dependencies.jar'
  doFirst {
    manifest {
      attributes("Class-Path": configureGfshDepsJar.outputs.files.singleFile.text)
    }
  }
}

tasks.register('docs', Javadoc) {
  def docsDir = file("$buildDir/javadocs")
  options.addStringOption('Xdoclint:none', '-quiet')
  options.links("https://lucene.apache.org/core/6_4_1/core/")
  options.links("https://lucene.apache.org/core/6_4_1/queryparser/")
  options.links("https://docs.oracle.com/javase/8/docs/api/")
  options.encoding = 'UTF-8'
  title = "${productName} ${project.version}"
  destinationDir = docsDir

  configurations.getByName("javadocOnly").allDependencies.each() { proj ->
    proj.dependencyProject.tasks.withType(Javadoc).findAll { it.enabled }.each { javadocTask ->
      source += javadocTask.source
      classpath += javadocTask.classpath
      excludes += javadocTask.excludes
      includes += javadocTask.includes
    }
  }

  include 'org/apache/geode/**/'

  doLast {
    rootProject.subprojects.each { project ->
      copy {
        if (project.hasProperty('sourceSets')) {
          from project.sourceSets.main.resources.srcDirs
        }
        include 'javadoc-images/*'
        into docsDir
      }
    }
  }
}

distributions {
  src {
    baseName = 'apache-geode'
    contents {
      from rootProject.tasks.writeBuildInfo
      from (rootDir) {
        exclude 'KEYS'
        exclude '**/gradlew'
        exclude '**/gradlew.bat'
        exclude '**/gradle/wrapper/gradle-wrapper.jar'
        exclude '**/.gradle'
        exclude '**/.project'
        exclude '**/.classpath'
        exclude '**/.settings/**'
        exclude '**/build-eclipse/**'
        exclude '**/.idea/**'
        exclude '**/*.iml'
        exclude '**/*.ipr'
        exclude '**/*.iws'
        exclude '**/.travis.yml'
        exclude '**/tags'

        //These directories are generated on the jenkins server by gradle
        exclude 'caches'
        exclude 'daemon'
        exclude 'native'
        exclude 'wrapper'

        // These exclude the 'build' and 'out' artifact directories from Gradle and IntelliJ for each project
        exclude 'buildSrc/build'
        exclude 'buildSrc/out'
        rootProject.allprojects.each {
          def relPath = Paths.get(rootDir.getPath()).relativize(Paths.get(it.projectDir.getPath()))
          def relOut = relPath.resolve("out").toString()
          def relBuild = relPath.resolve("build").toString()
          exclude relOut
          exclude relBuild
        }
      }
    }
  }
  named('main') {
    baseName = 'apache-geode'
    contents {
      duplicatesStrategy 'exclude'
      exclude '*.asc'

      exclude '*.asc'
      exclude '*-sources.jar'
      exclude '*-javadoc.jar'

      from rootProject.file('README.md')

      from "${projectDir}/src/main/dist/"

      with copySpec {
        into('config')
        from {defaultCacheConfig}
        from {defaultDistributionConfig}
        from {
          (project(':geode-log4j').sourceSets.main.resources.files.find {
            it.name == 'log4j2.xml'
          })
        }
      }

      with copySpec {
        into('lib')
        from { dependentProjectNames.collect {
            [
              project(':'.concat(it)).configurations.runtimeClasspath,
              project(':'.concat(it)).configurations.archives.allArtifacts.files
            ]
          }.flatten()
        }

        from configurations.gfshDependencies

        //These tasks are included as closures (wrapped in {}) because gradle may evaluate
        //this CopySpec before it evaluates the geode-core build file.
        from {project(':geode-core').tasks.named('raJar')}
        from {project(':geode-core').tasks.named('jcaJar')}

        // dependency jars
        from tasks.named('depsJar')
        from tasks.named('gfshDepsJar')
      }

      with copySpec {
        into('tools/Extensions')

        from {project(':geode-web').configurations.archives.allArtifacts.files}
        from {project(':geode-web-api').configurations.archives.allArtifacts.files}
        from {project(':geode-web-management').configurations.archives.allArtifacts.files}

        exclude '*.jar'
      }

      with copySpec {
        into('tools/ClientProtocol')
        from {project(':geode-protobuf-messages').zip.outputs.files}
      }

      with copySpec {
        into('javadoc')
        from { docs }
      }

      with copySpec {
        into('tools/Pulse')
        from {project(':geode-pulse').configurations.archives.allArtifacts.files}
      }

      with copySpec {
        into('tools/Modules')

        from { project(':extensions:geode-modules-assembly').distTcServer }
        from { project(':extensions:geode-modules-assembly').distTcServer30 }
        from { project(':extensions:geode-modules-assembly').distTomcat }
        from { project(':extensions:geode-modules-assembly').distAppServer }
      }
    }
  }

}
// Distribution plugin does not allow configuring of the task, only the contents. So we set
// compression and classifier here
[tasks.named('distTar'),
 tasks.named('srcDistTar'),
]*.configure {
  compression Compression.GZIP
  extension 'tgz'
  build.dependsOn(it)
}
// Make build final task to generate all test and product resources
build.dependsOn(installDist)

tasks.named('srcDistTar').configure {
  classifier 'src'
}

[tasks.named('distZip'),
 tasks.named('srcDistZip'),
 tasks.named('dockerfileZip'),
 ]*.configure {
  enabled = false
}

tasks.withType(Test) {
  dependsOn installDist
  environment 'GEODE_HOME', "$buildDir/install/${distributions.main.baseName}"
}


acceptanceTest.dependsOn(rootProject.getTasksByName("publishToMavenLocal", true))
installDist.dependsOn ':extensions:geode-modules-assembly:dist'
distributedTest.dependsOn ':extensions:session-testing-war:war'
distributedTest.dependsOn ':geode-old-versions:build'
upgradeTest.dependsOn ':extensions:session-testing-war:war'
upgradeTest.dependsOn ':geode-old-versions:build'

/**Print the names of all jar files in a fileTree */
def printJars(tree) {
  tree.matching {include("**/*.jar")}.visit{ file ->
    if(!file.isDirectory()) {
      println file.name
    }
  }
}

task dumpInstalledJars(dependsOn: installDist) {
  doLast {
    description "Dump a list of all of the jars shipped with the binary distribution, for validation purposes"

    FileTree installDir = fileTree(dir: installDist.destinationDir)

    println("Jars in the binary install")
    println("==========================")
    printJars(installDir)

    installDir.include("**/*.war").visit{ file ->
      if(!file.isDirectory()) {
          FileTree warContents = zipTree(file.file)
          println ""
          println file.name
          println("==========================")
          printJars(warContents)
      }
    }
  }
}

docker {
  dependsOn(tasks.installDist)
  name geodeDockerImageName
  copySpec.from(tasks.installDist.outputs).into('geode')
}

acceptanceTest {
  if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
    dependsOn(tasks.docker)
  }
}

apply from: Paths.get("${rootDir}", 'gradle', 'japicmp.gradle')
