/*
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.
*/
 
defaultTasks 'assemble'

apply from: '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 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.1.5'  # NOT compile 'com.ibm.messaging:watson-iot:0.1.5'
  //     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']
    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: 'jacoco.gradle'
apply from: '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}${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'
  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}${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 '.git', '.gradle', '.settings'
  exclude '**/build/'           // gradle generated artifacts
  exclude '**/externalJars/'    // gradle generated artifacts for eclipse
  exclude '**/bin/'             // eclipse generated artifacts
  exclude '**/classes/'         // old ant generated artifacts
  exclude '**/classes.in/'      // our retrolambda processing cruft
  exclude '**/classes.out/'     // our retrolambda processing cruft
  exclude '**/*.class'          // final backstop just in case
  exclude 'target/**'           // old ant generated artifacts
  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 {
  description = 'clean aggregator'  // "release dependsOn clean" only does top-level clean
  dependsOn clean, filteredSubprojects*.clean
}

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
}

task wrapper(type: Wrapper) {
  jarFile = rootProject.file('.gradle-wrapper/gradle-wrapper.jar')
}
