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


import org.apache.geode.gradle.plugins.DependencyConstraints

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-lucene',
  ':geode-memcached',
  ':geode-old-client-support',
  ':geode-protobuf',
  ':geode-protobuf-messages',
  ':geode-rebalancer',
  ':geode-redis',
  ':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 from: "${rootDir}/${scriptDir}/publish.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'
  }
}

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

  geodeArchives project(':geode-common')
  geodeArchives project(':geode-connectors')
  geodeArchives project(':geode-core')
  geodeArchives project(':geode-cq')
  geodeArchives project(':geode-lucene')
  geodeArchives project(':geode-management')
  geodeArchives project(':geode-memcached')
  geodeArchives project(':geode-old-client-support')
  geodeArchives project(':geode-protobuf')
  geodeArchives project(':geode-protobuf-messages')
  geodeArchives project(':geode-rebalancer')
  geodeArchives project(':geode-redis')
  geodeArchives project(':geode-wan')
  geodeArchives project(':geode-web')
  geodeArchives project(':geode-web-api')
  geodeArchives project(':geode-web-management')

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

  testCompile(project(':geode-core'))
  testCompile(project(':geode-junit')) {
    exclude module: 'geode-core'
  }
  testRuntime(project(':geode-old-versions'))


  acceptanceTestRuntime(project(':geode-old-versions'))


  integrationTestCompile(project(':geode-core'))
  integrationTestCompile(project(':geode-junit')) {
    exclude module: 'geode-core'
  }
  integrationTestCompile(project(':geode-dunit')) {
    exclude module: 'geode-core'
  }
  integrationTestCompile(project(':geode-pulse'))
  integrationTestCompile(project(':geode-assembly:geode-assembly-test'))
  integrationTestCompile('org.apache.httpcomponents:httpclient')
  integrationTestCompile('javax.annotation:javax.annotation-api')

  integrationTestRuntime('io.swagger:swagger-annotations')


  distributedTestCompile(project(':geode-core'))
  distributedTestCompile(project(':geode-dunit')){
    exclude module: 'geode-core'
  }
  distributedTestCompile(project(':extensions:session-testing-war'))
  distributedTestCompile(project(':geode-assembly:geode-assembly-test'))
  distributedTestCompile('org.apache.httpcomponents:httpclient')
  distributedTestCompile('org.springframework:spring-web')
  distributedTestCompile(project(':geode-management'))
  distributedTestCompile(project(':geode-web-management'))
  distributedTestCompile('org.apache.logging.log4j:log4j-core::tests')
  distributedTestCompile('org.apache.logging.log4j:log4j-core::test-sources')

  distributedTestRuntime(project(':extensions:geode-modules-session-internal')) {
    exclude group: 'org.apache.tomcat'
  }
  distributedTestRuntime('org.codehaus.cargo:cargo-core-uberjar')
  distributedTestRuntime('io.swagger:swagger-annotations')
  distributedTestRuntime(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.
  acceptanceTestCompile(configurations.geodeArchives)
  acceptanceTestCompile(project(':geode-dunit')) {
    exclude module: 'geode-core'
  }
  acceptanceTestCompile(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.
  acceptanceTestCompile('org.gradle:gradle-tooling-api:5.1.1')


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

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


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

  upgradeTestRuntime(project(':geode-old-versions'))
  upgradeTestRuntime(project(':extensions:session-testing-war'))
  upgradeTestRuntime('org.codehaus.cargo:cargo-core-uberjar')
  upgradeTestRuntime('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 {
    parent.subprojects.each { project ->
      copy {
        from project.sourceSets.main.resources.srcDirs
        into docsDir
        include 'javadoc-images/*'
      }
    }
  }
}

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-core').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'),
 ]*.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)
      }
    }
  }
}
