/*
 * 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 = "1G"
}

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 from: 'maven-compat.gradle'
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()
}

def releaseApprovedProjects = allprojects.findAll( { project ->  rootProject.ext.releaseSpec.satisfiedBy( project ) } )

rat {
    excludes = [
        '**/.DS_Store/**', '**/._*',
        // Git Files
        '**/.git/**', '**/.gitignore',
        // Gradle Files
        'gradle/wrapper/**', 'gradlew', 'gradlew.bat', '**/.gradle/**',
        // Build Output
        '**/build/**', '**/derby.log',
        // IDE Files
        '**/.idea/**', '**/*.iml', '**/*.ipr', '**/*.iws',
        '**/.settings/**', '**/.classpath', '**/.project',
        '**/.gradletasknamecache', '**/private/cache/**',
        '**/.nb-gradle-properties', '**/.nb-gradle/**',
        // 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/',
  javanet: "http://download.java.net/maven/2",
  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( '.' ) )
  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
    // exclude '**/internal/**'
  }

  repositories {
    mavenCentral()
    maven { name 'ops4j-repo'; url repos_urls.ops4j }
    maven { name 'restlet-repo'; url repos_urls.restlet }
    maven { name 'maven2-repository.dev.java.net'; url repos_urls.javanet }
    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/content/repositories/releases"
  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" )
    documentationDir = new File( "$projectDir/src/docs" )
    testJavaDir = new File( "$projectDir/src/tests/java" )
    testScalaDir = new File( "$projectDir/src/tests/scala" )
  }

  // Actual code projects BEGIN -------------------------------------------
  if( ext.javaDir.isDirectory() || ext.scalaDir.isDirectory() ||
      ext.testJavaDir.isDirectory() || ext.testScalaDir.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
    }

    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 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}/buildSrc/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 = new File( "" + buildDir + '/docs/javadoc' )
  // Might need a classpath
  classpath = files( apiSources.collect { project ->
    project.sourceSets.main.compileClasspath
  } )
  options.links( "http://docs.oracle.com/javase/7/docs/api/" )
  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-svn/site/content/java/develop/javadocs/" )
  }
  else
  {
    into( "$rootProject.projectDir/../zest-svn/site/content/java/$version/javadocs/" )
  }
  from( 'build/docs/javadoc/' )
}


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

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 = '// This gradle build file has the sole purpose of downloading all dependencies in this directory.\n'
    goOfflineGradle += '// Use the following command: gradle -b go-offline.gradle download\n'
    goOfflineGradle += 'apply plugin: \'java\'\nconfigurations { download }\nrepositories {\n'
    def 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 this directory.\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'

    def handledDeps = []
    releaseApprovedProjects.each { p ->
      p.configurations.runtime.allDependencies.each { dep ->
        def depCoords = "${dep.group}:${dep.name}:${dep.version}"
        if( !dep.group.startsWith( 'org.qi4j' ) && !handledDeps.contains( depCoords ) ) {

          goOfflineGradle += "  download '$depCoords'\n"
          goOfflineGradle += "  // download '$depCoords:sources'\n"
          goOfflineGradle += "  // download '$depCoords:javadoc'\n"

          def gav = "<groupId>${dep.group}</groupId><artifactId>${dep.name}</artifactId><version>${dep.version}</version>"
          goOfflinePom += """    <dependency>$gav</dependency>
          <!-- <dependency>$gav<classifier>sources</classifier></dependency> -->
          <!-- <dependency>$gav<classifier>javadoc</classifier></dependency> -->\n"""

          handledDeps << depCoords
        }
      }
    }

    goOfflineGradle += '}\ntask download( type: Copy ) {\n  from configurations.download\n  into file( \'dependencies/\' )\n}\n'
    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</id><phase>validate</phase>
      <goals><goal>copy-dependencies</goal></goals>
      <configuration><outputDirectory>\${project.basedir}/dependencies</outputDirectory></configuration>
    </execution></executions>
  </plugin></plugins></build>
</project>
"""

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

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

def srcDistImage = copySpec {
  from '.'
  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 '**/gradle.properties'    // Gradle properties
  exclude '**/.gradletasknamecache' // Gradle cache
  into "qi4j-sdk-$version/"
}

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 "qi4j-sdk-$version"
  with binDistNoticesImage
  with docsImage
  with reportsDistImage
  with runtimeDependenciesListImage
  with libsImage
}

task zipSources( type: Zip, dependsOn: buildAll ) {
  baseName = 'qi4j-sdk'
  with srcDistImage
  classifier = 'src'
}

task tarSources( type: Tar, dependsOn: buildAll ) {
  baseName = 'qi4j-sdk'
  with srcDistImage
  compression = Compression.GZIP
  classifier = 'src'
}

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

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

artifacts {
  archives zipSources, tarSources, zipBinaries, tarBinaries
}

task dist( type: Copy, dependsOn: install ) {
  with binDistImage
  into "$buildDir/dist"
}

// Tasks for source and binary distributions checks
// - Run the check task of this very build inside the source distribution
// - Rat the binary distribution (not pulled by checkDists as it takes ages to complete)
// - Use the dependencies download facility of the binary distribution to "go offline"
def unpackedSrcDistDir = file( "build/unpacked-distributions/src/qi4j-sdk-$version" )
def unpackedBinDistDir = file( "build/unpacked-distributions/bin/qi4j-sdk-$version" )
task unpackSrcDist( type: Copy ) {
  with srcDistImage
  into 'build/unpacked-distributions/src'
}
task checkSrcDist( type: GradleBuild, dependsOn: unpackSrcDist ) {
  buildFile = "$unpackedSrcDistDir/build.gradle"
  tasks = [ 'check' ] // TODO check
}
task unpackBinDist( type: Copy, dependsOn: buildAll ) {
  with binDistImage
  into 'build/unpacked-distributions/bin'
}
task checkBinDist_rat( type: org.apache.rat.gradle.RatTask, dependsOn: unpackBinDist ) {
  inputDir = unpackedBinDistDir
  reportDir = file( 'build/reports/rat-bin-dist' )
  excludes = []
}
task checkBinDist_goOfflineGradle( type: GradleBuild, dependsOn: unpackBinDist ) {
  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 ) {
  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', '-q', '-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 {
  dependsOn /*checkBinDist_rat,*/ checkBinDist_goOfflineGradle, checkBinDist_goOfflineMaven
}
task checkDists {
  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) /wrapper which is a directory named by the "jarPath" config which contains other needed files.
task wrapper( type: Wrapper ) {
  gradleVersion = '2.4'
}
