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

project.ext {
  title = "Apache Zest™ (Java Edition) SDK"
  description = "Apache Zest™ (Java Edition) is a framework for domain centric application development, including evolved concepts from AOP, DI and DDD."
  testFailures = [ ]
  mainClassName = 'org.qi4j.container.Main'
  groovycMain_mx = "700m"
  groovycMain_permSize = "512m"
  groovycMain_maxPermSize = "512m"
}

buildscript {
  repositories {
    maven { url "https://plugins.gradle.org/m2/" }
    jcenter()
  }
  dependencies {
    classpath 'gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.1.2'
    classpath 'gradle.plugin.org.nosphere.honker:honker-gradle:0.2.1'
    classpath 'org.hibernate.build.gradle:gradle-maven-publish-auth:2.0.1'
  }
}


apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'signing'
apply plugin: 'maven'
apply plugin: 'maven-publish-auth'
apply plugin: 'project-report'
apply from: 'libraries.gradle'
apply plugin: 'org.nosphere.apache.rat'

targetCompatibility = "1.7"
sourceCompatibility = "1.7"

// Collect the modules that fulfills the Release Criteria.
project.ext {
  releaseSpec = new org.qi4j.gradle.plugin.ModuleReleaseSpecification()
  releaseApprovedProjects = allprojects.findAll( { p -> rootProject.releaseSpec.satisfiedBy( p ) } )
}

// Toggle signing, used by the source distribution by setting the skipSigning property in gradle.properties
project.ext.skipSigning = rootProject.hasProperty( 'skipSigning' ) ? rootProject.skipSigning : false

rat {
    onlyIf { version != '0' }
    excludes = [
        '**/.DS_Store/**', '**/._*',
        // Git Files
        '**/.git/**', '**/.gitignore',
        // Gradle Files
        'gradle/wrapper/**', '**/gradlew', '**/gradlew.bat', '**/.gradle/**',
        // Build Output
        '**/build/**', '**/derby.log', 'out/**',
        // IDE Files
        '**/.idea/**', '**/*.iml', '**/*.ipr', '**/*.iws',
        '**/.settings/**', '**/.classpath', '**/.project',
        '**/.gradletasknamecache', '**/private/cache/**',
        '**/.nb-gradle-properties', '**/.nb-gradle/**',
        // JSON files are not allowed to have comments, according to http://www.json.org/ and http://www.ietf.org/rfc/rfc4627.txt
        '**/*.json',
        // Various Text Resources
        '**/README.*','**/README*.*', '**/TODO',
        '**/src/main/resources/**/*.txt',
        '**/src/test/resources/**/*.txt',
        'libraries/rest-server/src/main/resources/**/*.htm',
        'libraries/rest-server/src/main/resources/**/*.atom',
        'tools/qidea/src/main/resources/**/*.ft',
        'tools/qidea/src/main/resources/**/*.template',
        // Graphic Resources
        '**/*.svg', '**/*.gif', '**/*.png', '**/*.jpg', '**/*.psd',
        // Keystores
        '**/*.jceks',
        // Syntax Highlighter - MIT
        'manual/**/sh*.css', 'manual/**/sh*.js',
        // jQuery & plugins - MIT
        'manual/**/jquery*.js',
        // W3C XML Schemas - W3C Software License
        'samples/rental/src/main/resources/*.xsd',
    ]
}


// External tools BEGIN ---------------------------------------------------

// IDEA plugin configuration
idea.project.ipr {
  withXml { provider ->
    provider.node.component.find { it.@name == 'VcsDirectoryMappings' }.mapping.@vcs = 'Git'
  }
}

// External tools END -----------------------------------------------------

// Define repositories URLs here so we can reuse them in the build script
// Needed as Gradle forbid access to declared repositories URLs by design
// Releasable submodules should not declare repositories in their own build files
def repos_urls = [
  mavenCentral: "http://repo1.maven.org/maven2/",
  ops4j: "http://repository.ops4j.org/maven2/",
  restlet: 'http://maven.restlet.org/',
  clojars: "http://clojars.org/repo/",
]

allprojects {

  apply plugin: 'eclipse'
  apply plugin: 'idea'
  apply plugin: 'signing'
  apply plugin: 'java'
//  apply plugin: 'checkstyle'
  apply plugin: 'project-report'
  apply plugin: 'maven'
  apply plugin: 'org.nosphere.honker'


  defaultTasks 'classes', 'test'

  group = name == 'org.qi4j' ? 'org.qi4j' : name.substring( 0, name.lastIndexOf( '.' ) )
  if( version == 'unspecified' ) {
    version = System.properties.version ?: "0"
  }
  
  // UTF-8 For all compilations and javadocs
  // Deprecation warnings for all compilations
  // Unchecked warnings for non-test core compilations
  tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
    options.compilerArgs << "-Xlint:deprecation"
  }
  if("core".equals(group)) {
    tasks.matching({ task -> task instanceof JavaCompile && !task.name.contains('test') }).
        each({ task -> task.options.compilerArgs << "-Xlint:unchecked" })
  }
  tasks.withType(Javadoc) {
    options.encoding = 'UTF-8'
    options.docEncoding = 'UTF-8'
    options.charSet = 'UTF-8'
    options.noTimestamp = true
    options.links = [
      'http://docs.oracle.com/javase/7/docs/api/',
      'http://www.joda.org/joda-time/apidocs/',
      'http://www.json.org/javadoc/',
      'http://junit.org/javadoc/latest/'
    ]
    // exclude '**/internal/**'
  }

  repositories {
    mavenCentral()
    maven { name 'ops4j-repo'; url repos_urls.ops4j }
    maven { name 'restlet-repo'; url repos_urls.restlet }
    maven { name 'clojars-repo'; url repos_urls.clojars }
  }

  // Artifact upload global configuration BEGIN -----------------------------

  def uploadSnapshots = version.contains("SNAPSHOT")
  def uploadReleases = ! uploadSnapshots
  // By default RELEASES are signed, SNAPSHOTS are not
  // Signing can be turned on or off by setting the uploadSigned property
  def uploadSigned = rootProject.hasProperty('uploadSigned') \
                        ? rootProject.uploadSigned : uploadReleases \
                        ? true : false
  // By default RELEASES must satisfy ReleaseSpecification, SNAPSHOT don't
  // ReleaseSpecification usage can be turned on or off by setting the uploadReleaseSpec property
  def uploadReleaseSpec = rootProject.hasProperty('uploadReleaseSpec') \
                             ? rootProject.uploadReleaseSpec : uploadReleases \
                             ? true : false
  // By default RELEASES and SNAPSHOTS are uploaded using HTTP
  // Used Wagon can be overriden by setting the uploadWagon property
  // def wagonSSH = "org.apache.maven.wagon:wagon-ssh:2.2"
  // def wagonWEBDAV = "org.apache.maven.wagon:wagon-webdav:1.0-beta-2"
  def wagonHTTP = "org.apache.maven.wagon:wagon-http:2.2"
  def uploadWagon = rootProject.hasProperty('uploadWagon') \
                        ? rootProject.uploadWagon : wagonHTTP
  // By default RELEASES and SNAPSHOTS are uploaded to Apache Nexus
  // Target repository can be overriden by setting the uploadRepository property
  def releasesRepositoryName = "apache.releases.https"
  def releasesRepository = "https://repository.apache.org/service/local/staging/deploy/maven2"
  def snapshotsRepositoryName = "apache.snapshots.https"
  def snapshotsRepository = "https://repository.apache.org/content/repositories/snapshots"
  def uploadRepositoryName = rootProject.hasProperty('uploadRepositoryName') \
                            ? rootProject.uploadRepositoryName \
                            : uploadReleases ? releasesRepositoryName : snapshotsRepositoryName
  def uploadRepository = rootProject.hasProperty('uploadRepository') \
                            ? rootProject.uploadRepository \
                            : uploadReleases ? releasesRepository : snapshotsRepository
  // No username/password is provided by default
  // If needed set them using the uploadUsername and uploadPassword properties
  def uploadUsername = rootProject.hasProperty('uploadUsername') ? rootProject.uploadUsername : null
  def uploadPassword = rootProject.hasProperty('uploadPassword') ? rootProject.uploadPassword : null

  // Artifact upload global configuration END -------------------------------


  configurations {
    archives
    deployerJars
    provided
    compile.extendsFrom provided
    runtime.extendsFrom compile
  }

  dependencies {
    testCompile( libraries.ant )
    testCompile( libraries.ant_junit )
    testCompile( libraries.junit )
    testRuntime( libraries.asm, libraries.asm_commons, libraries.asm_util )
    deployerJars( uploadWagon )
  }

  test.onlyIf { !project.hasProperty( 'skipTests' ) }
  test {
      testLogging {
          info {
              exceptionFormat "full"
          }
      }
  }

  sourceSets {
    main {
      output.dir( honkerGenDependencies.outputDir, builtBy: honkerGenDependencies )
      output.dir( honkerGenLicense.outputDir, builtBy: honkerGenLicense )
      output.dir( honkerGenNotice.outputDir, builtBy: honkerGenNotice )
    }
    docs {
      resources {
        srcDir 'src/docs'
      }
    }
  }

  honker {
    // Project License, applied to all submodules
    license 'Apache 2'
    // Dependencies (transitive or not) with no license information, overriding them
    licenseOverride { candidate ->
      if( candidate.group == 'asm' || candidate.module == 'prefuse-core' ) {
        candidate.license = 'BSD 3-Clause'
      }
      if( candidate.group == 'org.apache.httpcomponents'
          || candidate.group == 'jdbm'
          || candidate.group == 'org.osgi'
          || candidate.group.startsWith( 'org.restlet' ) ) {
        candidate.license = 'Apache 2'
      }
    }
  }
  honkerGenNotice {
    header = 'Apache Zest'
    footer = 'This product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n'
  }
  check.dependsOn honkerCheck

  project.ext {
    javaDir = new File( "$projectDir/src/main/java" )
    scalaDir = new File( "$projectDir/src/main/scala" )
    groovyDir = new File( "$projectDir/src/main/groovy")
    documentationDir = new File( "$projectDir/src/docs" )
    testJavaDir = new File( "$projectDir/src/tests/java" )
    testScalaDir = new File( "$projectDir/src/tests/scala" )
    testGroovyDir = new File( "$projectDir/src/tests/groovy")
  }

  // Actual code projects BEGIN -------------------------------------------
  if( ext.javaDir.isDirectory() || ext.scalaDir.isDirectory() || ext.groovyDir.isDirectory() ||
      ext.testJavaDir.isDirectory() || ext.testScalaDir.isDirectory() || ext.testGroovyDir.isDirectory() )
  {
    apply plugin: 'jacoco'
    apply plugin: 'osgi'
    apply plugin: VersionClass
    apply plugin: AsciidocBuildInfo

//    if( name == "org.qi4j.core.runtime" )
//    {
//      checkstyleMain {
//        configFile = new File( "$rootProject.projectDir.absolutePath/etc/qi4j-runtime-checkstyle.xml" )
//        ignoreFailures = true
//      }
//    }
//    else
//    {
//      checkstyleMain {
//        configFile = new File( rootProject.projectDir.absolutePath.toString() + '/etc/qi4j-api-checkstyle.xml' )
//        ignoreFailures = true
//        reporting.baseDir = "$rootProject.reporting.baseDir/checkstyle"
//      }
//    }
//    checkstyleTest {
//      configFile = new File( "$rootProject.projectDir.absolutePath/etc/qi4j-tests-checkstyle.xml" )
//      ignoreFailures = true
//    }
//
//    checkstyleVersion {
//      configFile = new File( "$rootProject.projectDir.absolutePath/etc/qi4j-tests-checkstyle.xml" )
//      ignoreFailures = true
//    }

    jar {
      manifest {
        license = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
        docURL = 'https://zest.apache.org'
        description = project.description ?: 'Apache Zest™ (Java Edition) is a platform for Composite Oriented Programming'
        vendor = 'The Apache Software Foundation, https://www.apache.org'
        instruction '-debug', 'true'
      }
    }

    signing {
      required { rootProject.version != '0' && uploadSigned }
      sign configurations.archives
    }
    signArchives.onlyIf { !rootProject.skipSigning }

    task sourceJar( type: Jar ) {
      classifier = "sources"
      from sourceSets.main.allSource
    }

    task testSourceJar( type: Jar ) {
      classifier = "testsources"
      from sourceSets.test.allSource
    }

    task javadocJar( type: Jar ) {
      classifier = "javadoc"
      from javadoc.destinationDir
      dependsOn javadoc
    }

    artifacts {
      archives sourceJar, testSourceJar, javadocJar
    }

    def testProperties = [
            'proxySet': System.properties[ 'proxySet' ],
            'proxyHost': System.properties[ 'proxyHost' ],
            'proxyPort': System.properties[ 'proxyPort' ] ]

    test {
      maxHeapSize = "1024m"
      systemProperties = testProperties
      systemProperties['user.dir'] = workingDir // GRADLE-2859
      ignoreFailures = true
      reports.html.enabled(true)
      afterSuite { descriptor, result ->
        if( result.resultType == TestResult.ResultType.FAILURE )
        {
          rootProject.ext.testFailures << project
        }
      }
    }
    jacoco {
      toolVersion = '0.7.2.201409121644'
    }

//    // Create checkstyle report
//    task checkstyleReport( type: Xslt, dependsOn: check ) {
//      source project.checkstyle.reportsDir
//      include '*.xml'
//      destDir = file( "build/reports/checkstyle/" )
//      extension = 'html'
//      stylesheetFile = file( "$rootProject.projectDir/etc/checkstyle-noframes.xsl" )
//    }
//

    // Dependency Report generate only the runtime configuration
    // The report is packaged in the SDK distributions
    dependencyReport {
        configurations = [ project.configurations.runtime ]
    }

    task minBuild {
      dependsOn classes
      dependsOn test
    }

  }
  // Actual code projects END ---------------------------------------------

  // Upload Archives - Artifact Deployment
  uploadArchives.doFirst {
    if( version == "0" )
    {
      throw new GradleException( "'version' must be given as a system property to perform a release." )
    }
  }

  uploadArchives.onlyIf { ( !uploadReleaseSpec || ( releaseApprovedProjects.contains( project ) || project == rootProject ) ) && !project.hasProperty( 'skipUpload' ) }
  uploadArchives {
    dependsOn check
    repositories.mavenDeployer {
      if( uploadSigned )
        beforeDeployment { MavenDeployment deployment -> signing.signPom( deployment ) }
      configuration = configurations.deployerJars
      repository(id: uploadRepositoryName, url: uploadRepository) {
        if( uploadUsername )
          authentication(userName: uploadUsername, password: uploadPassword)
      }
      snapshotRepository(id: uploadRepositoryName, url: uploadRepository) {
        if( uploadUsername )
          authentication(userName: uploadUsername, password: uploadPassword)
      }
    }
  }
  apply from: "$rootProject.projectDir/maven-compat.gradle"
  apply plugin: 'maven-publish-auth' // Bug in maven-publish-auth require apply after uploadArchives setup

  idea.module.iml {
    whenMerged { module ->
      module.dependencies*.exported = true
    }
  }
} // allprojects END -------------------------------------------------------

// Allow easy download of all dependencies to go offline
// ./gradlew goOffline
task goOffline {
  doLast {
    allprojects.configurations.flatten()*.resolvedConfiguration
  }
}

gradle.taskGraph.whenReady {taskGraph ->
  taskGraph.allTasks.last().doLast {
    if( rootProject.ext.testFailures )
    {
      println "\nTest failures in:"
      rootProject.ext.testFailures.unique().each { project -> println "  " + project.name }
      println ""
      throw new RuntimeException( "There was TEST FAILURES!! See list above." )
    }
  }
}

task globalTestReport( type: TestReport ) {
  destinationDir = file("$buildDir/reports/tests")
  reportOn subprojects*.test
}

test {
  dependsOn subprojects*.test, globalTestReport
  reports.html.enabled = false
}

// Jacoco
configurations {
  jacoco
}
dependencies {
  jacoco 'org.jacoco:org.jacoco.ant:0.7.2.201409121644'
}
// Generate a global code codeverage report
task coverageReport {
  dependsOn subprojects*.test
  def outputPath = "build/reports/coverage"
  def coveredProjects = subprojects.findAll { p -> new File( "${p.buildDir.path}/jacoco" ).exists() }
  def coreProjects = coveredProjects.findAll { p -> p.name.startsWith('org.qi4j.core' ) }
  def libProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.qi4j.lib' ) }
  def extProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.qi4j.ext' ) }
  def toolsProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.qi4j.tool' ) }
  def tutoProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.qi4j.tuto' ) }
  def samplesProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.qi4j.sample' ) }
  ant {
    taskdef name:'jacocoreport', classname: 'org.jacoco.ant.ReportTask', classpath: configurations.jacoco.asPath
    mkdir dir: outputPath
    jacocoreport {
      executiondata {
        coveredProjects.collect { p -> fileset( dir: "${p.buildDir.path}/jacoco" ) { include( name: '*.exec' ) } }
      }
      structure( name: "Apache Zest™ (Java Edition) SDK" ) {
        group( name: "Core" ) {
          classfiles { coreProjects.collect { p -> fileset dir: "${p.buildDir.path}/classes/main" } }
          sourcefiles { coreProjects.collect { p -> fileset dir: "${p.projectDir.path}/src/main/java" } }
        }
        group( name: "Libraries" ) {
          classfiles { libProjects.collect { p -> fileset dir: "${p.buildDir.path}/classes/main" } }
          sourcefiles { libProjects.collect { p -> fileset dir: "${p.projectDir.path}/src/main/java" } }
        }
        group( name: "Extensions" ) {
          classfiles { extProjects.collect { p -> fileset dir: "${p.buildDir.path}/classes/main" } }
          sourcefiles { extProjects.collect { p -> fileset dir: "${p.projectDir.path}/src/main/java" } }
        }
        group( name: "Tools" ) {
          classfiles { toolsProjects.collect { p -> fileset dir: "${p.buildDir.path}/classes/main" } }
          sourcefiles { toolsProjects.collect { p -> fileset dir: "${p.projectDir.path}/src/main/java" } }
        }
        group( name: "Tutorials" ) {
          classfiles { tutoProjects.collect { p -> fileset dir: "${p.buildDir.path}/classes/main" } }
          sourcefiles { tutoProjects.collect { p -> fileset dir: "${p.projectDir.path}/src/main/java" } }
        }
        group( name: "Samples" ) {
          classfiles { samplesProjects.collect { p -> fileset dir: "${p.buildDir.path}/classes/main" } }
          sourcefiles { samplesProjects.collect { p -> fileset dir: "${p.projectDir.path}/src/main/java" } }
        }
      }
      csv  destfile: "${outputPath}/jacoco.csv", encoding: "UTF-8"
      xml  destfile: "${outputPath}/jacoco.xml", encoding: "UTF-8"
      html destdir:  outputPath, encoding: "UTF-8", locale: "en", footer: "Apache Zest™ (Java Edition) SDK"
    }
  }
  inputs.dir subprojects.collect { p -> "${p.buildDir.path}/jacoco" }
  outputs.dir outputPath
}


// Build the whole SDK public Javadoc
task javadocs( type: Javadoc ) {

  options.docFilesSubDirs = true
  options.encoding = "UTF-8"
  options.overview = "${rootProject.projectDir}/src/javadoc/overview.html"
  title = "${rootProject.title} ${version}"
  def apiSources = releaseApprovedProjects.findAll( { project ->
    ( project.name.startsWith( 'org.qi4j.core' ) && !project.name.startsWith( 'org.qi4j.core.runtime' ) ) ||
    project.name.startsWith( 'org.qi4j.library' ) ||
    project.name.startsWith( 'org.qi4j.extension' ) ||
    project.name.startsWith( 'org.qi4j.tool' )
  } )
  source apiSources.collect { project ->
    project.sourceSets.main.allJava
  }
  destinationDir = project.file( "$project.docsDir/javadocs" )
  // Might need a classpath
  classpath = files( apiSources.collect { project ->
    project.sourceSets.main.compileClasspath
  } )
  options.group( [ "Core API": [ "org.qi4j.api", "org.qi4j.api.*", "org.qi4j.io", "org.qi4j.functional" ],
                         "Core Bootstrap": [ "org.qi4j.bootstrap", "org.qi4j.bootstrap.*" ],
                         "Core SPI": [ "org.qi4j.spi", "org.qi4j.spi.*" ],
                         "Libraries": [ "org.qi4j.library.*", "org.qi4j.logging", "org.qi4j.logging.*", "org.qi4j.lang.*" ],
                         "Extensions": [ "org.qi4j.valueserialization.*", "org.qi4j.entitystore.*", "org.qi4j.index.*", "org.qi4j.metrics.*", "org.qi4j.cache.*", "org.qi4j.migration", "org.qi4j.migration.*" ],
                         "Tools": [ "org.qi4j.tools.*", "org.qi4j.envisage", "org.qi4j.envisage.*", "org.qi4j.library.swing.entityviewer" ],
                         "Test Support": [ "org.qi4j.test", "org.qi4j.test.*" ]
                 ] )

}

task archiveJavadocs(type: Copy ) {
  dependsOn javadocs

  if( rootProject.version == '0' || rootProject.version.contains( "SNAPSHOT" ) )
  {
    into( "$rootProject.projectDir/../zest-web/site/content/java/develop/javadocs/" )
  }
  else
  {
    into( "$rootProject.projectDir/../zest-web/site/content/java/$version/javadocs/" )
  }
  from( 'build/docs/javadoc/' )
}


// Build All
task buildAll( dependsOn: [
    javadocs,
    check,
    jar,
    subprojects*.dependencyReport,
    subprojects*.assemble,
    ':org.qi4j.manual:website'
] ) { }

// Generate license headers with comment styles
def licenseHeader_wrap( base, top, left, bottom ) {
  ( top ? "$top\n" : '' ) + base.readLines().collect{ "${left}${it}" }.join( '\n' ) + '\n' + ( bottom ? "$bottom\n" : '' )
}
def licenseHeader( flavour ) {
  def base = project.file( 'etc/header.txt' ).text
  def header
  switch( flavour ) {
    case 'java': case 'groovy': case 'scala': case 'js':
      header = licenseHeader_wrap( base, '/*', ' * ', ' */' ) ; break
    case 'xml': case 'html':
      header = licenseHeader_wrap( base, '<!--', '  ', '-->' ) ; break
    case 'txt': case 'shell': case 'python': case 'ruby':
      header = licenseHeader_wrap( base, null, '# ', null ) ; break
    case 'adoc': case 'asciidoc':
      header = licenseHeader_wrap( base, null, '// ', null ) ; break
    default:
      header = base
  }
  header
}

task generateBinDistGoOfflineHelpers {
  def goOfflineGradleFile = file( 'build/go-offline-helpers/go-offline.gradle' )
  def goOfflinePomFile = file( 'build/go-offline-helpers/go-offline.pom')
  outputs.files goOfflineGradleFile
  outputs.files goOfflinePomFile
  doLast {

    def goOfflineGradle = licenseHeader( 'java' )
    goOfflineGradle += '// This gradle build file has the sole purpose of downloading all dependencies in a directory relative to this file named \'dependencies\'.\n'
    goOfflineGradle += '// Use the following command: gradle -b go-offline.gradle download\n'
    goOfflineGradle += 'apply plugin: \'java\'\nconfigurations { download }\nrepositories {\n'
    def goOfflinePom = licenseHeader( 'xml' )
    goOfflinePom += '<project>\n  <modelVersion>4.0.0</modelVersion>\n'
    goOfflinePom += "  <groupId>org.qi4j</groupId>\n  <artifactId>go-offline-helper</artifactId>\n  <version>$version</version>\n"
    goOfflinePom += '  <packaging>pom</packaging>\n'
    goOfflinePom += '  <!--\n  This pom has the sole purpose of downloading all dependencies in a directory relative to this file named \'dependencies\'.\n'
    goOfflinePom += '  Use the following command:\n\n  mvn -f go-offline.pom validate\n  -->\n  <repositories>\n'

    def repoCount = 1
    repos_urls.each { repo_url ->
      goOfflineGradle += "  maven { url '${repo_url.value}' }\n"
      goOfflinePom += "    <repository><id>go-offline-repo-$repoCount</id><url>${repo_url.value}</url></repository>\n"
      repoCount++
    }

    goOfflineGradle += '}\ndependencies {\n'
    goOfflinePom += '  </repositories>\n  <dependencies>\n'

    // Do the global dependency resolution here so there won't be any suprise when using the helpers
    // This also allow to apply the resolution strategy defined in libraries.gradle
    // WARN some of our modules depends on != versions of some artifacts, this resolution flatten this using the most up to date
    def allRuntimeDeps = releaseApprovedProjects.collect{ it.configurations.runtime.allDependencies }.flatten()
    rootProject.configurations.create( 'goOfflineHelpers' )
    rootProject.dependencies { allRuntimeDeps.each{ goOfflineHelpers it } }
    rootProject.configurations.goOfflineHelpers.incoming.resolutionResult.allComponents.each { comp ->
      def depCoords = "${comp.moduleVersion.group}:${comp.moduleVersion.name}:${comp.moduleVersion.version}"
      if( !comp.moduleVersion.group.startsWith( 'org.qi4j' ) ) {
        goOfflineGradle += "  download( '$depCoords' ) { transitive = false }\n"
        goOfflinePom += "    <dependency><groupId>${comp.moduleVersion.group}</groupId><artifactId>${comp.moduleVersion.name}</artifactId><version>${comp.moduleVersion.version}</version></dependency>\n"
      }
    }

    goOfflineGradle += """}
task download( type: Copy ) {
  def sources = configurations.download.resolvedConfiguration.resolvedArtifacts.collect { artifact ->
    project.dependencies.create( [ group: artifact.moduleVersion.id.group, name: artifact.moduleVersion.id.name, version: artifact.moduleVersion.id.version, classifier: 'sources' ] )
  }
  def javadocs = configurations.download.resolvedConfiguration.resolvedArtifacts.collect { artifact ->
    project.dependencies.create( [ group: artifact.moduleVersion.id.group, name: artifact.moduleVersion.id.name, version: artifact.moduleVersion.id.version, classifier: 'javadoc' ] )
  }
  from configurations.download
  from configurations.detachedConfiguration( sources as Dependency[] ).resolvedConfiguration.lenientConfiguration.getFiles( Specs.SATISFIES_ALL )
  from configurations.detachedConfiguration( javadocs as Dependency[] ).resolvedConfiguration.lenientConfiguration.getFiles( Specs.SATISFIES_ALL )
  into file( 'dependencies/' )
}
"""

    goOfflinePom += """  </dependencies>\n  <build><plugins><plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
      <execution>
        <id>go-offline-jars</id><phase>validate</phase>
        <goals><goal>copy-dependencies</goal></goals>
        <configuration>
          <outputDirectory>\${project.basedir}/dependencies</outputDirectory>
          <excludeTransitive>true</excludeTransitive>
        </configuration>
      </execution>
      <execution>
        <id>go-offline-sources</id><phase>validate</phase>
        <goals><goal>copy-dependencies</goal></goals>
        <configuration>
          <classifier>sources</classifier><failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
          <outputDirectory>\${project.basedir}/dependencies</outputDirectory>
          <excludeTransitive>true</excludeTransitive>
        </configuration>
      </execution>
      <execution>
        <id>go-offline-javadocs</id><phase>validate</phase>
        <goals><goal>copy-dependencies</goal></goals>
        <configuration>
          <classifier>javadoc</classifier><failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
          <outputDirectory>\${project.basedir}/dependencies</outputDirectory>
          <excludeTransitive>true</excludeTransitive>
        </configuration>
      </execution>
    </executions>
  </plugin></plugins></build>
</project>
"""

    goOfflineGradleFile.parentFile.mkdirs()
    goOfflinePomFile.parentFile.mkdirs()

    goOfflineGradleFile.text = goOfflineGradle
    goOfflinePomFile.text = goOfflinePom
  }
}


def srcDistFilesImages = copySpec {
  from '.'
  include '*.txt'
  include 'doap.rdf'
  include '*.gradle'
  include 'gradlew*'
  include 'gradle/**'
  include 'etc/**'
  include 'buildSrc/**'
  include 'src/**'
  releaseApprovedProjects.each { p ->
    def relPath = new File( project.projectDir.toURI().relativize( p.projectDir.toURI() ).toString() )
    include "$relPath/**"
  }
  include 'manual/**'
  include 'samples/**'
  include 'tests/**'
  include 'tutorials/**'
  // Filtered, see below
  exclude 'settings.gradle'
  exclude 'gradle.properties'
  // Excludes
  exclude '**/build/'               // Build output
  exclude 'derby.log'               // Derby test garbage
  exclude '**/*.iml'                // IDEA files
  exclude '**/*.ipr'                // IDEA files
  exclude '**/*.iws'                // IDEA files
  exclude '**/.idea'                // IDEA files
  exclude '**/out/*'                // IDEA build output
  exclude '**/.classpath'           // Eclipse files
  exclude '**/.project'             // Eclipse files
  exclude '**/.settings'            // Eclipse files
  exclude '**/.nb-gradle/'          // Netbeans files
  exclude '**/.nb-gradle*'          // Netbeans files
  exclude '**/.git/'                // Git directories
  exclude '**/.git*'                // Git files
  exclude '**/.gradle/'             // Gradle management files
  exclude '**/.gradletasknamecache' // Gradle cache
  into '.'
}

task srcDistFilteredFiles() {
  // Generates various files for the source distribution
  // - settings.gradle
  // - gradle.properties to set version !
  def filteredDir = new File( "$project.buildDir/tmp/srcDistFilteredFiles")
  outputs.file filteredDir
  doLast {
    // Settings
    def settingsFile = new File( filteredDir,  'settings.gradle' )
    settingsFile.parentFile.mkdirs()
    def filteredSettings = ''
    project.file( 'settings.gradle' ).readLines().each { line ->
      if( line.contains( '\'libraries:' ) || line.contains( '\'extensions:' ) || line.contains( '\'tools:' ) ) {
        def accepted = false
        releaseApprovedProjects.collect{it.projectDir}.each { acceptedProjectDir ->
          if( line.contains( "'${acceptedProjectDir.parentFile.name}:${acceptedProjectDir.name}'" ) ) {
            accepted = true
          }
        }
        if( accepted ) {
          filteredSettings += "$line\n"
        }
      } else {
        filteredSettings += "$line\n"
      }
    }
    settingsFile.text = filteredSettings
    // gradle.properties
    def gradlePropsFile = new File( filteredDir, 'gradle.properties' )
    gradlePropsFile.parentFile.mkdirs()
    gradlePropsFile.text = project.file( 'gradle.properties' ).text + "\nskipSigning=true\nskipAsciidocIfAbsent=true\n\nversion=$version\n"
  }
}

def srcDistFilteredFilesImage = copySpec {
  from srcDistFilteredFiles
  into '.'
}

def srcDistImage = copySpec {
  into "apache-zest-java-$version-src"
  with srcDistFilesImages
  with srcDistFilteredFilesImage
}

def reportsDistImage = copySpec {
  from "$buildDir/reports"
  into( "docs/reports" )
}

def docsImage = copySpec {
  from "build/docs"
  from "manual/build/docs/website"
  into( "docs" )
}

def runtimeDependenciesListImage = copySpec {
  releaseApprovedProjects.collect { p ->
    into( "libs/" ) {
      from "$p.buildDir/reports/project/dependencies.txt"
      rename 'dependencies.txt', "${p.name}-${p.version}-runtime-deps.txt"
    }
  }
  into( '.' ) {
    from generateBinDistGoOfflineHelpers.outputs
  }
}

def libsImage = copySpec {
  releaseApprovedProjects.collect { proj ->
    into( "libs/" ) {
      from proj.configurations.archives.artifacts.files
      exclude '**-testsources.jar'
      exclude '**/*.asc'
    }
  }
}

def binDistNoticesImage = copySpec {
  from( "$projectDir/LICENSE.txt")
  from( "$projectDir/src/bin-dist" )
  into( "." )
}

def binDistImage = copySpec {
  into "apache-zest-java-$version-bin"
  with binDistNoticesImage
  with docsImage
  with reportsDistImage
  with runtimeDependenciesListImage
  with libsImage
}

task zipSources( type: Zip ) {
  baseName = 'apache-zest-java'
  with srcDistImage
  classifier = 'src'
}

task tarSources( type: Tar ) {
  baseName = 'apache-zest-java'
  with srcDistImage
  compression = Compression.GZIP
  classifier = 'src'
}

task zipBinaries( type: Zip, dependsOn: buildAll ) {
  baseName = 'apache-zest-java'
  classifier = 'bin'
  with binDistImage
}

task tarBinaries( type: Tar, dependsOn: buildAll ) {
  baseName = 'apache-zest-java'
  classifier = 'bin'
  compression = Compression.GZIP
  with binDistImage
}

// Checksum distributions
tasks.withType( Zip ) { task ->
  task.doLast {
    ant.checksum file: task.archivePath, algorithm: 'MD5'
    ant.checksum file: task.archivePath, algorithm: 'SHA-512'
  }
}
tasks.withType( Tar ) { task ->
  task.doLast {
    ant.checksum file: task.archivePath, algorithm: 'MD5'
    ant.checksum file: task.archivePath, algorithm: 'SHA-512'
  }
}

artifacts {
  archives zipSources, tarSources, zipBinaries, tarBinaries
}

signing {
  required { rootProject.version != '0' && !rootProject.version.contains( 'SNAPSHOT' ) }
  sign configurations.archives
}
signArchives.onlyIf { !rootProject.skipSigning }

task dist( type: Copy, dependsOn: install ) {
  description "Unpack the binary distribution"
  group = "distributions"
  with binDistImage
  into "$buildDir/dist"
}

// Tasks for source and binary distributions checks
def unpackedSrcDistDir = file( "build/unpacked-distributions/src/apache-zest-java-$version-src" )
def unpackedBinDistDir = file( "build/unpacked-distributions/bin/apache-zest-java-$version-bin" )
task unpackSrcDist( type: Copy ) {
  description "Unpack the source distribution"
  group = "distributions"
  with srcDistImage
  into 'build/unpacked-distributions/src'
}
task checkSrcDist( type: GradleBuild, dependsOn: unpackSrcDist ) {
  description = "Check the source distribution by running the 'check' and 'assemble' tasks inside"
  group = "distributions"
  buildFile = "$unpackedSrcDistDir/build.gradle"
  tasks = [ 'check', 'assemble' ]
}
task unpackBinDist( type: Copy, dependsOn: buildAll ) {
  description "Unpack the binary distribution"
  group = "distributions"
  with binDistImage
  into 'build/unpacked-distributions/bin'
}
task checkBinDist_rat( type: org.apache.rat.gradle.RatTask, dependsOn: unpackBinDist ) {
  description "Check the binary distribution using Apache RAT"
  group = "distributions"
  inputDir = unpackedBinDistDir
  reportDir = file( 'build/reports/rat-bin-dist' )
  excludes = []
}
task checkBinDist_goOfflineGradle( type: GradleBuild, dependsOn: unpackBinDist ) {
  description "Check the binary distribution Gradle go-offline helper"
  group = "distributions"
  def dependenciesDir = new File( unpackedBinDistDir, 'dependencies' )
  doFirst { dependenciesDir.deleteDir() }
  buildFile = "$unpackedBinDistDir/go-offline.gradle"
  tasks = [ 'download' ]
  doLast {
    releaseApprovedProjects*.configurations.runtime.allDependencies.findAll({it.name}).each { dep ->
      def jarArtifactId = dep.name instanceof String ? dep.name : dep.name.last()
      def jarVersion = dep.version instanceof String ? dep.version : dep.version.last()
      if( !jarArtifactId.startsWith( 'org.qi4j' ) ) {
        def jarName = "${jarArtifactId}-${jarVersion}.jar"
        if( !new File( dependenciesDir, jarName ).exists() ) {
          throw new GradleException( "Binary distribution go-offline.gradle failed! Missing: $jarName" );
        }
      }
    }
  }
}
task checkBinDist_goOfflineMaven( type: Exec, dependsOn: unpackBinDist ) {
  description "Check the binary distribution Maven go-offline helper"
  group = "distributions"
  onlyIf {
    def pathDirs = System.getenv( 'PATH' ).split( File.pathSeparator )
    pathDirs.collect( { new File( it, 'mvn') } ).flatten().findAll( { it.isFile() } )
  }
  def dependenciesDir = new File( unpackedBinDistDir, 'dependencies' )
  doFirst { dependenciesDir.deleteDir() }
  workingDir unpackedBinDistDir
  commandLine 'mvn', '-e', '-f', 'go-offline.pom', 'validate'
  doLast {
    releaseApprovedProjects*.configurations.runtime.allDependencies.findAll({it.name}).each { dep ->
      def jarArtifactId = dep.name instanceof String ? dep.name : dep.name.last()
      def jarVersion = dep.version instanceof String ? dep.version : dep.version.last()
      if( !jarArtifactId.startsWith( 'org.qi4j' ) ) {
        def jarName = "${jarArtifactId}-${jarVersion}.jar"
        if( !new File( dependenciesDir, jarName ).exists() ) {
          throw new GradleException( "Binary distribution go-offline.pom failed! Missing: $jarName" );
        }
      }
    }
  }
}
task checkBinDist {
  description "Check the binary distribution"
  group = "distributions"
  dependsOn /*checkBinDist_rat,*/ checkBinDist_goOfflineGradle, checkBinDist_goOfflineMaven
}
task checkDists {
  description "Check the souce and binary distributions"
  group = "distributions"
  dependsOn checkSrcDist, checkBinDist
}

task checkReleaseSpec {
  description = "Ensure that no releasable module depend on module(s) that don't fit the release criteria."
  group = 'release'
  dependsOn releaseApprovedProjects*.configurations.runtime
  doFirst {
    def notReleasable = [:]
    releaseApprovedProjects*.configurations.runtime.allDependencies.findAll({ it instanceof ProjectDependency }).each { dep ->
      def depNotReleaseApproved = releaseApprovedProjects.findAll { rp ->
        rp.group == dep.dependencyProject.group && rp.name == dep.dependencyProject.name 
      }.isEmpty()
      if( depNotReleaseApproved )
      {
        if( !notReleasable[p] ) notReleasable[p] = []
        notReleasable[p] << dep
      }
    }
    if(!notReleasable.isEmpty()) {
      def errorMessage = new StringBuilder()
      errorMessage << "At least one releasable module depends on module(s) that don't fit the release criteria!\n"
      errorMessage << "\tOffending module -> Non releasable dependencies\n"
      notReleasable.each { k,v ->
        def noRlsDeps = v.collect{d -> ':'+d.dependencyProject.group+':'+d.dependencyProject.name}
        errorMessage << "\t$k -> ${noRlsDeps})\n"
      }
      errorMessage << "Check the dev-status.xml file content in each modules directory."
      throw new GradleException( errorMessage.toString() )
    }
  }
}

task release {
  description = 'Builds, tests and uploads the release artifacts'
  group = 'release'
  doFirst {
    if( System.properties[ 'version' ] == null || System.properties[ 'version' ].contains( 'SNAPSHOT' ) )
    {
      throw new GradleException( "'version' must be given as a system property to perform a release." )
    }
  }
  dependsOn checkReleaseSpec, rat, archiveJavadocs, ':org.qi4j.manual:copyWebsite', allprojects*.uploadArchives, dist
}

//
// This is a task that generates the gradlew scripts, allowing users to run gradle without having gradle installed
// on their system.
// This task should be run by "build master" and the resulting ouput committed to source control.  Its outputs include:
//  1) /gradlew which is the *NIX shell script for executing builds
//  2) /gradlew.bat which is the windows bat script for for executing builds
//  3) /gradle/wrapper which is a directory named by the "jarPath" config which contains other needed files.
task wrapper( type: Wrapper ) {
  gradleVersion = '2.5'
}
