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


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

import java.nio.file.Paths

evaluationDependsOn(":geode-core")

apply plugin: 'distribution'
apply from: "${project.projectDir}/../gradle/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)

// disable artifact generation for this project
jar.enabled = false

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

publishing {
  publications {
    maven(MavenPublication) {
      afterEvaluate {
        artifactId = artifactName

        artifacts = []

        artifact distTar
      }
    }
  }
}

signing {
  afterEvaluate {
    sign distTar
    sign srcDistTar
  }
}

logger.info("Gradle doesn't automatically remove the jar artifact even though we disabled it")
logger.info("this causes publishing to fail.  So we nuke all the disabled artifacts from all configurations.")
configurations.all {
  def configName = it.name
  artifacts.each {
    logger.info("Pruning configName = " + configName + " name=" + it.name + " extension=" + it.extension + " classifier=" + it.classifier)
  }
  artifacts.removeAll{ it.name == jar.baseName && it.extension == 'jar' && it.classifier == jar.classifier }
  if (artifacts) {
    logger.info("Artifacts are now: " + artifacts)
  }
}

gradle.taskGraph.whenReady( { graph ->
  tasks.withType(Tar).each { tar ->
    tar.compression = Compression.GZIP
    tar.extension = 'tgz'
  }
  tasks.srcDistTar {
    classifier 'src'
  }
  tasks.withType(Jar).each { jarTasks ->
    distTar.dependsOn(jarTasks)
  }

  tasks.distZip.enabled = false
  tasks.srcDistZip.enabled = false

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

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

configurations {
  gfshDependencies

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

  javadocOnly {
    description 'Projects that must be included in the JavaDocs.'
    extendsFrom archives
  }
}

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

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

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


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


  acceptanceTestCompile(project(':geode-core'))
  acceptanceTestCompile(project(':geode-dunit')) {
    exclude module: 'geode-core'
  }
  acceptanceTestCompile(project(':geode-assembly:geode-assembly-test'))
  acceptanceTestCompile('org.apache.httpcomponents:httpclient')
  
  // 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
}

task defaultDistributionConfig(type: JavaExec, dependsOn: classes) {
  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()
  }
}

task defaultCacheConfig(type: JavaExec, dependsOn: classes) {
  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.archives.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.archives.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(' ')
}

task configureDepsJar(dependsOn: configurations.archives.dependencies) {
  def output = project.buildDir.toPath().resolve('reports').resolve('deps_jar_cp.txt')
  outputs.file {
    output
  }
  doLast {
    output.write(cp())
  }
}

task configureGfshDepsJar(dependsOn: configurations.gfshDependencies.dependencies) {
  inputs.files {
    configureDepsJar
  }
  inputs.files {
    project(':geode-core').webJar
  }

  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
task depsJar (type: 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)
    }
  }
}

task gfshDepsJar (type: 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)
    }
  }
}

def docsDir = file("$buildDir/javadocs")
task docs(type: Javadoc) {
  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
        }
      }
    }
  }

  main {
    baseName = 'apache-geode'
    contents {
      duplicatesStrategy 'exclude'
      exclude '*.asc'

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

      from rootProject.file( 'README.md' )

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

      into ('lib') {
        from project(':geode-common').configurations.runtimeClasspath
        from project(':geode-common').configurations.archives.allArtifacts.files
        from project(':geode-wan').configurations.runtimeClasspath
        from project(':geode-wan').configurations.archives.allArtifacts.files
        from project(':geode-cq').configurations.runtimeClasspath
        from project(':geode-cq').configurations.archives.allArtifacts.files
        from project(':geode-core').configurations.runtimeClasspath
        from project(':geode-core').configurations.archives.allArtifacts.files
        from project(':geode-lucene').configurations.runtimeClasspath
        from project(':geode-lucene').configurations.archives.allArtifacts.files
        from project(':geode-redis').configurations.runtimeClasspath
        from project(':geode-redis').configurations.runtimeClasspath.allArtifacts.files
        from project(':geode-connectors').configurations.runtimeClasspath
        from project(':geode-connectors').configurations.archives.allArtifacts.files
        from project(':geode-old-client-support').configurations.runtimeClasspath
        from project(':geode-old-client-support').configurations.archives.allArtifacts.files
        from project(':geode-protobuf').configurations.runtimeClasspath
        from project(':geode-protobuf').configurations.archives.allArtifacts.files
        from project(':geode-protobuf-messages').configurations.runtimeClasspath
        from project(':geode-protobuf-messages').configurations.archives.allArtifacts.files
        from project(':geode-rebalancer').configurations.runtimeClasspath
        from project(':geode-rebalancer').configurations.archives.allArtifacts.files

        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').webJar }
        from { project(':geode-core').raJar }
        from { project(':geode-core').jcaJar }

        // dependency jars
        from depsJar
        from gfshDepsJar
      }

      into ('tools/Extensions') {
        from (project(':geode-web').configurations.archives.allArtifacts.files) {
          exclude '*.jar'
        }
        from (project(':geode-web-api').configurations.archives.allArtifacts.files) {
          exclude '*.jar'
        }
        from (project(':geode-web-management').configurations.archives.allArtifacts.files) {
          exclude '*.jar'
        }
      }

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

      into ('javadoc') {
        from docs
      }

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

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

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

// Make build final task to generate all test and product resources
build.dependsOn installDist

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