/*
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: 'gradle/wrapper.gradle'
apply from: 'gradle/other.gradle'

import org.gradle.plugins.signing.Sign
import java.io.Console
 
/* Configure root project */
allprojects {
  apply plugin: 'idea'
  apply plugin: 'eclipse'

  repositories {
    mavenCentral()
  }
  
  project.version = build_version
}

apply from: 'gradle/rat.gradle'

rat {
  excludes = [
    '*.patch',
    '**/.classpath',
    '**/.cache/**',
    '**/.git/**',
    '**/.gitignore',
    '**/.gradle/**',
    '.gradle-wrapper/**',  // historical instead of gradle/wrapper
    '**/.idea/**',
    '**/.project',
    '**/.settings/**',
    '**/bin/**',           // generated by Eclipse builds
    '**/build/**',
    '**/META-INF/services/**',
    '**/README.md',
    'externalJars/**',     // generated by setupExternalJars for Eclipse use
    'gradlew',
    'gradlew.bat',
    'DEVELOPMENT.md',
    'JAVA_SUPPORT.md',
    'CONTRIBUTORS', '.mailmap',
    'binary-release/apache-notice',
    'binary-release/ibm-contrib-notice',
    'connectors/jdbc/JdbcStreamsTestDb/**',
    'connectors/jdbc/derby.log',
    'connectors/mqtt/src/test/keystores/**',
    'console/**/js/ext/**/jquery.js',         // has header w/MIT license ref
    'console/**/js/ext/**/jquery-ui.min.css', // has header w/MIT license ref
    'console/**/js/ext/**/jquery-ui.min.js',  // has header w/MIT license ref
    'console/**/js/ext/**/jquery-ui.structure.min.css', // has header w/MIT license ref
    'console/**/js/ext/**/jquery-ui.theme.min.css', // has header w/MIT license ref
    'console/**/js/ext/d3.legend.js',         // has header w/MIT license ref
    'console/**/js/ext/d3.min.js',            // no header. included in LICENSE
    'console/**/js/ext/sankey_edgent.js',     // no header. included in LICENSE
    'licenses/d3-sankey.BSD',                 // OK, BSD 3-clause
    'licenses/d3.BSD',                        // OK, BSD 3-clause
    'licenses/binary-release/javax.servlet-api-3.1.0.CDDL-1.0',  // OK, only binary form content
    'licenses/binary-release/javax.websocket-api-1.0.CDDL-1.1',  // OK, only binary form content
    'licenses/binary-release/mqttv3-1.1.0.EDL-1.0',  // OK, EDL-1.0
    'licenses/binary-release/mqttv3-1.1.0.EDL-1.0',  // OK, EDL-1.0
    'licenses/binary-release/watson-iot-0.2.2.EPL-1.0',  // OK, only binary form content
    'samples/**/*.properties',
    'samples/**/*.cfg',
    'scripts/**/*.properties',
    'scripts/**/device.cfg',
    'scripts/connectors/jdbc/persondata.txt',
    'scripts/connectors/kafka/README-kafka',
    'test/**/*.properties',
    'test/**/device.cfg',
    'test/**/*.txt',
  ]
}

apply plugin: 'java'
jar {
  deleteAllActions()  // Avoid creating/staging an empty jar for the "root"
}
apply plugin: 'signing'


ext {
  commithash_error = ''
  commithash = {
    try {
      return "git rev-parse --short HEAD".execute().text.trim()
    } catch (Exception e) {
      ext.commithash_error = e
      return ''
    }
  }()
  now = new Date()
  DSTAMP = String.format('%tY%<tm%<td', now)
  TSTAMP = String.format('%tH%<tM', now)
  COPYRIGHT_YEAR = String.format('%tY', now)
  
  snapshotId = "-SNAPSHOT-${DSTAMP}-${TSTAMP}"
  if (System.properties['edgent.snapshotId'] != null) {
    snapshotId = System.properties['edgent.snapshotId']
  }
                   
  external_jars_dir = "$rootProject.projectDir/externalJars/java8"
  
  target_dir = "$distsDir"
  target_java8_dir = "$target_dir/java8"
  target_java8_ext_dir = "$target_java8_dir/ext"
  target_java7_dir = "$target_dir/java7"
  target_android_dir = "$target_dir/android"
  target_docs_dir = "$target_dir/docs"
  target_javadoc_dir = "$target_docs_dir/javadoc"
  target_report_dir = "$target_dir/reports"
 
  // project groups whose jars are to be placed in target_java8_lib
  // instead of the default "$target_java8_dir/$simpleProjectGroup/$project.name/lib"
  //         e.g., "$target_java8_dir/lib" for api/topology
  //         "$target_java8_dir/connectors/iotp/lib" for connectors/iotp
  //
  target_java8_lib_groups = ["api", "providers", "runtime", "spi"]
  
  // TODO can these be deduced by the absence of a build.gradle for the project?
  aggregatorOnlyProjects = [
    ':android',
    ':analytics', ':api', ':apps',
    ':connectors', ':console',
    ':platform', ':providers',
    ':runtime', ':samples', ':spi',
    ':test', ':utils'
  ]
  
  filteredSubprojects = subprojects.findAll { 
    project -> !aggregatorOnlyProjects.contains(project.path)
  }
  
  // Edgent core external dependencies
  core_ext_dependencies = ['com.google.code.gson:gson:2.2.4',
                   'org.slf4j:slf4j-api:1.7.12',
                   'io.dropwizard.metrics:metrics-core:3.1.2']
  
  // Edgent Samples external dependencies
  samples_ext_dependencies = ['org.slf4j:slf4j-jdk14:1.7.12']

  // Edgent tests external dependencies
  test_common_dependencies = ['org.slf4j:slf4j-jdk14:1.7.12']
  
  common_ext_dependencies = [
    core_ext_dependencies,
    samples_ext_dependencies,
    // test_common_dependencies, // omit as tests aren't included in release tgz
  ].flatten()

  ext."signing.keyId" = null
  ext."signing.secretKeyRingFile" = null
  ext."signing.password" = null
}

// Declare the common_ext_dependencies as dependencies of the root project
// to easily copy them (their resolved paths) to the target dir
dependencies {
  compile common_ext_dependencies
}
ext.copyCommonExtJarsFn = { targetDir ->
  copy {
    from configurations.compile.files
    into targetDir
  }
}
task setupCommonExtJars << {
  copyCommonExtJarsFn "$external_jars_dir/ext"
}
task copyCommonExtJars << {
  copyCommonExtJarsFn target_java8_ext_dir
}

def String mkJarNameFromSpec(String jarSpec) {
  // e.g. 'com.google.code.gson:gson:2.2.4' => gson-2.2.4.jar
  // e.g. 'com.google.code.gson:gson:2.2.4@jar' => gson-2.2.4.jar
  def sfx = jarSpec.endsWith('@jar') ? "" : '.jar'
  return jarSpec.split(':')[1] + '-' + jarSpec.split(':')[2].replace('@','.') + sfx
}

def getProjectExtDepFiles(Project proj) { // project's direct ext deps and their transitive deps
  // TODO suspect this is picking up ext dependencies of transitive **project** dependencies???
  
  // handle ext jar deps expressed via "compile <external-dependency-spec>"
  def allExtDepFiles = proj.configurations.runtime.files { it instanceof ExternalDependency }
  
  // handle ext jar deps expressed via addTargetDirExtJarDependency
  allExtDepFiles.addAll proj.files(proj.directTargetDirExtJarDependencies)
  
  logger.info "$proj.path allExtDepFiles: "+allExtDepFiles
  return allExtDepFiles
}
 
def getProjectNonCommonExtDepFiles(Project proj) {
  // filter out "common" (target_java8_ext_dir) external dependencies
  def commonExtJarNames = common_ext_dependencies.collect {
    mkJarNameFromSpec it
  }
  def filteredExtDepFiles = getProjectExtDepFiles(proj).findAll {
    ! commonExtJarNames.contains(it.getName())
  }
  return filteredExtDepFiles
}

def String mkManifestClassPath(Project proj) {
  // The manifest's classpath needs to include the project's:
  // - immediate-only dependant edgent jars (not transitive and not their ext deps
  //   since our project jars are build with a manifest-classpath that
  //   handles the project's "private" dependencies)
  // - immediate dependant external jars and their transitive deps (since
  //   these don't seem to have a manifest classpath that takes care of their
  //   dependencies)
  // - common_ext_dependencies jars when declared as dependencies
  //
  // proj.configurations.runtime.files (mostly) captures all of the above
  // since do to our project build.gradle use of our various add*Dependency().

  def depJars = proj.configurations.runtime.files
    
  // assume that any deps still in the gradle cache are project private ext deps
  // (that will-get/have-been copied into the project's ext dir in the targetdir) 
  def projExtDir = "$target_java8_dir/$proj.targetRelProjExtDir"
  depJars = depJars.collect { file ->
    if (file.toString().contains('/.gradle/caches/')) {
      return proj.file("$projExtDir/"+file.getName())
    }
    return file
  }
    
  def cp = proj.mkRelativePaths(depJars).join(' ')
  logger.info "$proj.path manifest-classPath: $cp"
  return cp
}

gradle.taskGraph.whenReady {taskGraph ->
  if (taskGraph.hasTask(test)) {
    println "\nHINTs: Use the '--tests <testClassNamePattern>[.<testMethodNamePattern>]' option to select specific test classes or methods."
    println "    ./gradlew :api:topology:test --tests '*JsonFunctionsTest'"
    println "    ./gradlew :api:topology:test --tests '*JsonFunctionsTest.testBytes'"
    println "Use the 'cleanTest' task to force a rerun of a previously successful test task:"
    println "    ./gradlew :api:topology:cleanTest :api:topology:test"
    println "    ./gradlew cleanTest test"
    println ""
    sleep 2
  }
}

/* Configure subprojects */
subprojects {

  // ignore aggregator only projects so we don't assemble empty jars, etc for them.
  if (aggregatorOnlyProjects.contains(project.path)) {
    return
  }
  
  if(!project.group.equals("edgent.platform")){
  	apply plugin: 'maven-publish'
  }
  apply plugin: 'java'
  apply plugin: "jacoco"
 
  if (buildFile.isFile() && !buildFile.exists()) {
    configurations.create('default')
    return
  }
  
  ext.simpleGroupName = project.group.replace('edgent.', '') // e.g., 'edgent.api' => 'api'

  ext.mkRelativePaths = { Collection files ->
    // make all files paths relative to the project's lib dir in targetdir
    // well... unless this is for a war, which resides in the group's "webapps"
    // dir instead of project's lib dir.  See :console:servlets build.gradle.
    def projLibDir = project.file("$target_java8_dir/$targetRelProjLibDir")
    if (project.pluginManager.hasPlugin('war')) {
      projLibDir = project.file("$target_java8_dir/$project.simpleGroupName/webapps")
    }
    files.collect {  projLibDir.toPath().relativize(it.toPath()) }
  }

  ext.targetRelProjDir = { String kind ->  // kind: "lib", "ext"
    // use targetRelProject{Lib,Ext}Dir
    // e.g., =>  "lib" or "<component>/<subcomponent>/lib"
    // the general case location
    def relProjDir = "$simpleGroupName/$project.name/$kind"
   
    // special cases
    if (target_java8_lib_groups.contains(simpleGroupName)) {
      relProjDir = "$kind"
    }
    else if ('samples' == simpleGroupName) {
      relProjDir = "samples/$kind"
    }
   
    return relProjDir
  }
  ext.targetRelProjLibDir = targetRelProjDir('lib')
  ext.targetRelProjExtDir = targetRelProjDir('ext')
  
  // N.B. regarding the various add*Dependency() methods
  //
  // The methods need to be used in project build.gradle "dependencies" declarations.
  // e.g.,
  //   dependencies {
  //     addTargetDirProjectJarDependency 'compile', ':api:topology' # NOT compile project(':api:topology')
  //     addProjectExtDependency 'compile', 'com.ibm.messaging:watson-iot:0.2.2'  # NOT compile 'com.ibm.messaging:watson-iot:0.2.2'
  //     addProjectExtDependency 'compile', 'org.apache.kafka:kafka_2.10:0.8.2.2@jar'
  //     addTargetDirCoreExtDependencies 'compile'
  //     addMyTargetDirProjectJarDependency 'testCompile'
  //     // N.B. root project adds test common dependencies
  //   }
  // 
  // These methods play a role in the policies:
  // - Edgent projects depend on other project's jars in the target-dir, not their classes
  // - Edgent project jars have a manifest-classpath that handles
  //   the project's "private" inter-project dependencies
  //   as well as the project's "private" external component dependencies.
  // - We build a target dir that includes the project's jar as well as
  //   the project's external dependency jars
  // - The tests compile and run against the project jars in the target dir
  //   (as external/integration test code would).
  // - The samples compile and run against the project jars in the target dir
  //   (as user code would).
  
  ext.directTargetDirExtJarDependencies = [] 

  ext.addTargetDirProjectJarDependency = { config,proj ->
    // add a dependency on a project's jar in the target-dir
    def jarPath = project(proj).jar.archivePath
    
    // add the jar as a dependency and ensure it's present when we need it
    // ? script error with: dependencies { "$config" files(jarPath) builtBy "${proj}:assemble" }
    dependencies { "$config" files(jarPath) }
    def task = "${config}Java"
    if (config == "testCompile") {
      task = "compileTestJava"
    }
    else if (config == "providedCompile") {
      task = "compileJava"
    }
    "$task" { dependsOn "${proj}:assemble" }
  }

  ext.addMyTargetDirProjectJarDependency = { config ->
    // add a dependency on my project's jar in the target dir
    addTargetDirProjectJarDependency(config, project.path)
  }
  
  ext.addTargetDirExtJarDependency = { config,jarName ->
    // add a dependency on a target_java8_ext_dir jarName
    // record the addition
    def jar = "$target_java8_ext_dir/$jarName"
    if (!directTargetDirExtJarDependencies.contains(jar)) {
      directTargetDirExtJarDependencies.add jar
    }
    
    // add the jar as a dependency
    dependencies { "$config" files(jar) }
    compileJava { dependsOn ':copyCommonExtJars' }
  }
  
  ext.addTargetDirCoreExtJarDependencies = { config ->
    core_ext_dependencies.collect { depSpec ->
      mkJarNameFromSpec(depSpec)
    }.each { jarName ->
      addTargetDirExtJarDependency config, jarName
    }
  }

  ext.addProjectExtDependency = { config,externalDepSpec ->
    // for declaring project private external dependencies
    // ends up (transitively) copying the dependency to the project's ext dir
    dependencies { "$config" externalDepSpec }
  }

  ext.addCompileTestDependencies = { String... deps ->
    // add a dependency on other project's testClasses
    deps.each { dep ->
      dependencies {
        testCompile project(dep).sourceSets.test.output
      }
      compileTestJava {
        dependsOn "${dep}:testClasses"
      }
    }
  }

  sourceCompatibility = '1.8'
  targetCompatibility = '1.8'

  def compileOptions = {
    options.debugOptions.debugLevel = 'source,lines,vars'
    options.verbose = logger.isDebugEnabled()
    options.listFiles = logger.isInfoEnabled()
    options.deprecation = true
    options.encoding = 'UTF-8'
  }
  compileJava {
    configure compileOptions
  }
  compileTestJava {
    configure compileOptions
  }
  
  dependencies {
    // common dependencies for tests
    testCompile 'junit:junit:4.10'
    addMyTargetDirProjectJarDependency 'testCompile'
    if (project.path != ':api:function') {
      addTargetDirExtJarDependency 'testRuntime', 'slf4j-jdk14-1.7.12.jar'
    }
    else {
      // the add... induces UnsupportedOperationException elsewhere in script when processing :api:function:jar ???
      // can't figure it out but cleaning directTargetDirExtJarDependencies
      // avoids it ???... with seemingly no other consequences.
      addTargetDirExtJarDependency 'testRuntime', 'slf4j-jdk14-1.7.12.jar'
      project.directTargetDirExtJarDependencies = []
    }

    // common dependencies for samples
    if (project.path ==~ '^:samples.*') {
      addTargetDirProjectJarDependency 'compile', ':providers:development'
      addTargetDirProjectJarDependency 'compile', ':providers:direct'

      addTargetDirCoreExtJarDependencies 'compile'      
      addTargetDirExtJarDependency 'runtime', 'slf4j-jdk14-1.7.12.jar'
    }
  }
  
  ext.copyProjectExtJarsFn = { targetDir ->
    // Copy the project jar's "private" external dependencies (transitively)
    // into the project's ext dir in the target-dir.

    // If our project's jar task lacks any actions (e.g., platform:android)
    // there's nothing to do.
    if (!jar.actions)
      return
    
    // FYI we're getting more transitive ext deps than the ant build
    // in some cases - e.g., for watson iot we "knew" we only needed a subset
    // of all watson iot deps known to maven
    
    def projectExtDir = project.targetRelProjExtDir
    def nonCommonExtFiles = getProjectNonCommonExtDepFiles(project)
    logger.info "$project.path copying projExtDepFiles jars: "+nonCommonExtFiles.collect { it.getName() }
    copy {
      from nonCommonExtFiles
      includeEmptyDirs = false
      into "$targetDir/$projectExtDir"
    }
  }
  
  ext.copyProjectExtJarsFn2 = { targetDir ->
    // Copy the project jar's "private" external dependencies (transitively)
    // into target-dir.
    
    def nonCommonExtFiles = getProjectNonCommonExtDepFiles(project)
    logger.info "$project.path copying projExtDepFiles jars: "+nonCommonExtFiles.collect { it.getName() }
    copy {
      from nonCommonExtFiles
      includeEmptyDirs = false
      into "$targetDir"
    }
  }
  
  task setupProjectExtJars << {
    // Helper for setupExternalJars task
    copyProjectExtJarsFn external_jars_dir
  }

  jar {
    // adjust jar task config and also augment the task to do our additional processing
    
    // generate the project's jar into the target dir location
    // with the appropriate name and manifest.
    // TODO - gradle/maven best practice has version in jarname
    
    archiveName = "${project.group}.${project.name}.${extension}"
    if (["javax.websocket-client", "javax.websocket-server", "edgent.javax.websocket"].contains(project.name)) {
      archiveName = "${project.name}.${extension}"
    }
    destinationDir = file("$target_java8_dir/" + targetRelProjLibDir)

    doFirst {
      configure jarOptions
    }
    
    doLast {
      copyProjectExtJarsFn target_java8_dir
    }
  }

  ext.jarOptions = {
    manifest {
      attributes(
        'Implementation-Title': "${-> baseName}",
        'Implementation-Vendor': build_vendor,
        // TODO inclusion of DSTAMP/TSTAMP results in regeneration
        // of a jar when none of its contents/dependencies have changed.
        // If possible use a canned DSTAMP/TSTAMP for non-"release" tasks
        // to make the dev cycle more efficient at the expense of the TSTAMP.
        'Implementation-Version': "${commithash}-${DSTAMP}-${TSTAMP}",
        'Class-Path': mkManifestClassPath(project),
      )
    }
    metaInf {
      with( copySpec {
        rename { 'LICENSE' }
        from rootProject.file('binary-release/apache-v2_0-license')
      })
      with( copySpec {
        rename { 'NOTICE' }
        from rootProject.file(
          projectsWithPreApacheContribs.contains(project.path)
            ? 'binary-release/ibm-contrib-notice'
            : 'binary-release/apache-notice')
      })
    }
  }
  
  ext.printFile = { path ->
    ant.concat { fileset(file: path) }
  }
  ext.adjustTest7Classpath = false
  
  task testSummaryFinalizer << {
    def testTask = tasks.getByName('test')
    if (System.properties['edgent.build.ci'] != null) {
      testTask.failedTestResultPaths.each { path ->
        println path
        printFile path
      }
    }
    def result = testTask.summaryResult
    if (result != null) {
      def duration = String.format('%.3fsec', (result.endTime - result.startTime) / 1000)
      println "$project.path $duration $result.resultType ($result.testCount tests, $result.failedTestCount failures, $result.skippedTestCount skipped)"
    }
  }

  test {
    filter {
      includeTestsMatching '*Test'  // can override via --tests command line option
    }

    systemProperty 'edgent.test.top.dir.file.path', rootProject.projectDir
    systemProperty 'edgent.test.root.dir', rootProject.projectDir
    systemProperty 'edgent.build.ci', System.properties['edgent.build.ci']
    
    // pass along any org.apache.edgent system props
    systemProperties System.properties.findAll { it.key.startsWith("org.apache.edgent") }
    
    testLogging {
      exceptionFormat 'full'
      showStandardStreams = System.properties['edgent.test.showOutput'] != null
    }
    beforeSuite { desc ->
      if (!desc.parent) { // will match the outermost suite
        println "$project.path testing ..."
      }
    }
    ext.failedTestResultPaths = []
    ext.summaryResult = null
    afterSuite { desc, result ->
      // make failures in edgent.build.ci runs more debuggable
      // wish the junit xml files existed at this moment but they don't
      if (desc.parent && desc.className != null) {  // individual test class result
        if (result.resultType == TestResult.ResultType.FAILURE) {
          def resultFile = "$testResultsDir/test/TEST-${desc.className}.xml"
          println "\nFailed testrun results: $resultFile"
          failedTestResultPaths.add resultFile
        }
      }
      else if (!desc.parent) { // project's overall results
        summaryResult = result 
      }
    }
    finalizedBy "testSummaryFinalizer" // a doLast isn't invoked if there's a test failure
    reports {
      junitXml.enabled = true  // generate build/test-results/test/TEST-*.xml
      // individual <project>/build/reports junit/jacoco html reports not needed with aggregate report
      html.enabled = System.properties['edgent.test.project.htmlReports'] != null
    }
    doFirst {
      // The project's tests are supposed to run against its target-dir jar.
      // We must remove the project's $buildDir/{classes,resources}/main
      // from the classpath so they're not used.  

      classpath = project.sourceSets.test.runtimeClasspath
      classpath -= project.sourceSets.main.output

      // Hmm... for some reason the classpath (when printed here) also includes
      // the project's src build/libs/ jar and by the default name
      // (e.g., build/libs/oplets-0.4.1.jar) yet we've configured the jar task
      // to generate the jar in the target-dir with a different name.  
      // It also lacks that target-dir jar we added as a dependency 
      // via addMyTargetDirProjectJarDependency 'testCompile'
      // ???  
      // Adjust accordingly.
      
      classpath = classpath.filter { ! it.path.startsWith(project.libsDir.path) } 
      classpath = files(project.jar.archivePath) + classpath
      
      if (adjustTest7Classpath) {
        // Add special java7 processing... (on top of the other test.doFirst classpath manipulations)
      
        // Change from using the normal test classes dir to the java7 test classes dir
        classpath -= files(sourceSets.test.output.classesDir)
        classpath = files(sourceSets.test.output.classesDir.toString().replace('test', 'java7Test')) + classpath
        
        // Some of the tests have dependencies on other tests, adjust those classpaths too
        classpath = files(classpath.collect { it.toString().replace('build/classes/test', 'build/classes/java7Test') })
      
        // Switch from java8 jars to java7 jars
        classpath = files(classpath.collect { it.toString().replace('java8', 'java7') })
      }
      logger.debug "$project.path test.classpath: " + classpath.collect { it.toString() }
    }
  }
  
  ext.j7TestClassesDir = file("$project.buildDir/classes/java7Test")
  
  task test7AdjustTestTask << {
    if (! tasks.getByName('test').enabled
        || unsupportedJava7TestProjects.contains(project.path)
        || sourceSets.test.allSource.isEmpty()) {
      test.enabled = false
      return
    }
    adjustTest7Classpath = true
    if (!j7TestClassesDir.exists()) {
      // implicit dependency: :platform:java7:test7Compile
      logger.error " ERROR: Run the test7Compile task.  $j7TestClassesDir does not exist."
      throw new TaskExecutionException()
    }
    test {
      testClassesDir = j7TestClassesDir
      outputs.upToDateWhen { false } // always run - task is never "up to date"
    }
  }

  task test7Run() {
    description = "Run the test7Compile'd tests against the java7 target jars - run after :platform:java7:test7Compile and with JAVA_HOME==java7-VM"
    // fwiw trying to leverage :platform:java7:ant_test7.run was problematic
    
    dependsOn ':platform:java7:verifyJava7Built', test7AdjustTestTask, test
    // implicit dependency: :platform:java7:test7Compile
    test.mustRunAfter = [ test7AdjustTestTask, ':platform:java7:verifyJava7Built' ]

    outputs.upToDateWhen { false } // always run - never "up to date"
  }

  assemble.doLast {
    // augment assemble with our additional target dir update processing
    
    // Copy SRC into target dir when appropriate
    if (project.path ==~ '^:samples.*') {
      copy {
        from(sourceSets.main.allSource.srcDirs) { include '**/*.java' }
        into "$target_java8_dir/$project.simpleGroupName/src/$project.name/src/main/java/"
      }
    }
  }
  
  task sourceJar(type: Jar) {
    // baseName-appendix-version-classifier.extension
    from sourceSets.main.allJava
    classifier = 'sources'
  }  

  // support for 'gradle publishToMavenLocal' etc 
  // TODO publishing test.{fvt,svt} and samples ... doesn't seem desirable? e.g., we're excluding test.{fvt,svt} jars from the tgz
  if (project.pluginManager.hasPlugin('publishing')) {
    publishing {
      publications {
        mavenJava(MavenPublication) {
          // specify dependencies like: org.apache.edgent:edgent.api.topology:0.4.0
          groupId = build_group
          artifactId = "${project.group}.${project.name}" 
          artifact sourceJar
          if (project.pluginManager.hasPlugin('war')) {
            from components.web
          }
          else {
            from components.java
          }
        }
      }
    }
  }
    
}

task copyScripts(type: Copy) {
  description = 'Copy scripts to target_java8_dir'
  includeEmptyDirs = false
  from("scripts/") { include "**/*" }
  into "$target_java8_dir/scripts/"
}

//Create Junit Report
// need to setup classpath to junit/jacoco for ant.junitreport task
configurations {
  junitLibs
}
dependencies { // versions with gradle 3.1
  junitLibs 'org.apache.ant:ant-junit:1.9.6'
  junitLibs 'org.apache.ant:ant-junit4:1.9.6'
  junitLibs 'org.jacoco:org.jacoco.ant:0.7.7.201606060606'
}

task createJunitReport << {
  description = "Generates a Junit report from all subprojects (use after 'test')"

  ant.delete(dir: "${target_report_dir}/tests")
  ant.taskdef(name: 'junitreport',
          classname: 'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator',
          classpath: configurations.junitLibs.asPath)
  ant.junitreport(todir: './') {
    fileset(dir: './', includes: '**/test-results/test/TEST-*.xml')
    report(format: 'frames', todir: "${target_report_dir}/tests")
  }
  ant.move(file: "TESTS-TestSuites.xml", tofile: "${target_report_dir}/TESTS-TestSuites.xml")
}

apply from: 'gradle/jacoco.gradle'
apply from: 'gradle/javadoc.gradle'

task addVersionDotTxt {
  description = 'Add version.txt in target_dir'
  doLast {
    def map = [
      DSTAMP: "$DSTAMP",
      TSTAMP: "$TSTAMP",
      commithash: "$commithash",
      'commithash.error': "$commithash_error",
      'edgent.version': "$build_version",
      ]
    def f = new File("$target_dir/version.txt");
    def d = new File(target_dir);
    if( !d.exists() ) { d.mkdirs() }
    f.createNewFile()
    map.forEach { k,v -> f.append "$k=$v\n" }
  }
}

task releaseTarGz(type: Tar) {
  description = 'Create binary release tgz in target_dir'
  archiveName = "apache-${build_name}-${build_version}-incubating${snapshotId}-bin.tgz"
  compression = Compression.GZIP
  destinationDir = new File("${target_dir}/../release-edgent")
  duplicatesStrategy 'exclude'
  into "${build_name}-${build_version}${snapshotId}"
  // make some things first in the tgz
  from rootProject.file('binary-release/LICENSE')
  from rootProject.file('binary-release/NOTICE')
  into ('licenses') { from 'licenses' }
  from 'DISCLAIMER', 'JAVA_SUPPORT.md'
  from rootProject.file('binary-release/README')
  from 'RELEASE_NOTES', 'CONTRIBUTORS'
  from "$target_dir/version.txt"
  from target_dir
  exclude '**/test/svt/'
  exclude '**/connectors/javax.websocket-server/' // just part of wsclient test harness
  doLast {
    ant.checksum algorithm: 'md5', file: archivePath
    ant.checksum algorithm: 'sha-512', fileext: '.sha', file: archivePath
    println "created $destinationDir/$archiveName"
  }
}  

task srcReleaseTarGz(type: Tar) {
  description = 'Create source release tgz in target_dir'
  archiveName = "apache-${build_name}-${build_version}-incubating${snapshotId}-src.tgz"
  compression = Compression.GZIP
  destinationDir = new File("${target_dir}/../release-edgent")
  duplicatesStrategy 'exclude'
  into "${build_name}-${build_version}${snapshotId}-src"
  // make some things first in the tgz
  from 'LICENSE', 'NOTICE'
  from 'DISCLAIMER', 'JAVA_SUPPORT.md'
  from 'RELEASE_NOTES'
  from 'README'
  exclude 'README.md'
  from 'DEVELOPMENT.md'
  from '.'
  exclude 'KEYS'
  exclude '.git', '.gradle', '.settings'
  exclude '.gradle-wrapper', 'gradlew', 'gradlew.bat'
  exclude '**/build/'           // gradle generated artifacts
  exclude '**/externalJars/'    // gradle generated artifacts for eclipse
  exclude '**/bin/'             // eclipse generated artifacts
  exclude '**/*.class'          // final backstop just in case
  exclude 'connectors/jdbc/derby.log'         // test cruft
  exclude 'connectors/jdbc/JdbcStreamsTestDb' // test cruft
  doLast {
    ant.checksum algorithm: 'md5', file: archivePath
    ant.checksum algorithm: 'sha-512', fileext: '.sha', file: archivePath
    println "created $destinationDir/$archiveName"
  }
}  

gradle.taskGraph.whenReady { taskGraph ->
    if (ext."signing.password"==null && taskGraph.allTasks.any { it instanceof Sign }) {
        // Use Java console to read from the console (no good for a CI environment)
        def Console console = System.console()
        console.printf "\n\n#####################################" +
                       "\nWe have to sign some things in this build." +
                       "\nPlease enter your signing details.\n\n"
        def id = System.env['GPG_ID']
        try { 
          def tmpId = console.readLine("PGP Code Signing Key Id (default: $id): ")
          if (!tmpId.isEmpty())
            id = tmpId
        } catch (NullPointerException e) {
          throw new GradleException("You must run 'signAll --no-daemon'")
        }
        def file = System.env['GPG_SECRING']
        if (file == null) {
          file = "${System.properties['user.home']}/.gnupg/secring.gpg"
        }
        def tmpFile = console.readLine("PGP Secret Key Ring File (default: $file): ")
        if (!tmpFile.isEmpty()) {
          file = tmpFile
        }
        def password = String.valueOf(console.readPassword("PGP Private Key Password: "))

        allprojects { ext."signing.keyId" = id }
        allprojects { ext."signing.secretKeyRingFile" = file }
        allprojects { ext."signing.password" = password }

        console.printf "\n#####################################\n"
    }
}

task signAll(type: Sign) {
    description='Sign existing release artifacts in ${target_dir}/../release-edgent (run separetely after "release")'
    fileTree("${target_dir}/../release-edgent") {
        include '**/*.tgz'
    }.each {
      sign it
    }
    outputs.upToDateWhen { false }
    doFirst {
      if (getFilesToSign().isEmpty()) {
        throw new GradleException("No artifacts to sign. Run the 'release' task first.")
      }
      //println "### files to sign: " + getFilesToSign().collect { it.name }.join(",")
    }
    doLast {
      println "\nCreated signature files: " + getSignatureFiles().collect { it.name }.join(", ")
    }
}

assemble {
  description = "Assemble distribution artifacts and populate the target_dir with jars, doc, etc. Like 'build' w/o 'test'"
  dependsOn filteredSubprojects.assemble, aggregateJavadoc, copyScripts
  aggregateJavadoc.mustRunAfter filteredSubprojects*.assemble
}

task all(dependsOn: assemble) {
  description = "alias for 'assemble'"
}

task cleanAll(type: Delete) {
  description = 'clean aggregator'  // "release dependsOn clean" only does top-level clean
  dependsOn clean, filteredSubprojects*.clean
  // purge old ant build artifacts
  delete 'target'
  delete 'reports'
  delete fileTree(dir: '.', includes:['**/classes/', '**/test.classes/'])
  // retro7 processing cruft 
  delete fileTree(dir: '.', includes:['**/classes.in/', '**/classes.out/']) 
}

task release {
  description = 'Assemble distribution artifacts, populate target_dir, and create a release tgz'
  dependsOn cleanAll, addVersionDotTxt, assemble,
       ':platform:java7:addJava7TargetDir', ':platform:android:addAndroidTargetDir',
       srcReleaseTarGz, releaseTarGz
  addVersionDotTxt.mustRunAfter cleanAll
  assemble.mustRunAfter addVersionDotTxt
  releaseTarGz.mustRunAfter assemble,':platform:java7:addJava7TargetDir',':platform:android:addAndroidTargetDir'
}

task reports {
  description = "Generate JUnit and Coverage reports of prior test run. Use after 'test'"
  dependsOn createJunitReport, jacocoTestReport
}

task test7AdjustJacocoReport << {
  jacocoTestReport.test7AdjustJacocoReport = true
  logger.lifecycle "### NOTE: [WIP] test7 jacoco reporting ###"
}

task test7Reports {
  description = "Generate JUnit and Coverage reports of prior test run. Use after 'test7Run'"
  dependsOn createJunitReport, test7AdjustJacocoReport, jacocoTestReport
  jacocoTestReport.mustRunAfter test7AdjustJacocoReport
}

// build: inject test report generation and javadoc generation (for early problem detection)
// make 'build' like "all test reports"
build {
  dependsOn filteredSubprojects.build, reports
  reports.mustRunAfter filteredSubprojects.build 
}

task setupExternalJars {
  description = 'Add all of the dependant external jars to the target-dir (make available to Eclipse, etc)'
  dependsOn setupCommonExtJars, filteredSubprojects.setupProjectExtJars
}
