/*
 * 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.apache.zest.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.8"
sourceCompatibility = "1.8"

// Collect the modules that fulfills the Release Criteria.
project.ext {
  releaseSpec = new org.apache.zest.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.apache.zest' ? 'org.apache.zest' : 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.apache.zest.core.runtime" )
//    {
//      checkstyleMain {
//        configFile = new File( "$rootProject.projectDir.absolutePath/etc/zest-runtime-checkstyle.xml" )
//        ignoreFailures = true
//      }
//    }
//    else
//    {
//      checkstyleMain {
//        configFile = new File( rootProject.projectDir.absolutePath.toString() + '/etc/zest-api-checkstyle.xml' )
//        ignoreFailures = true
//        reporting.baseDir = "$rootProject.reporting.baseDir/checkstyle"
//      }
//    }
//    checkstyleTest {
//      configFile = new File( "$rootProject.projectDir.absolutePath/etc/zest-tests-checkstyle.xml" )
//      ignoreFailures = true
//    }
//
//    checkstyleVersion {
//      configFile = new File( "$rootProject.projectDir.absolutePath/etc/zest-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.5.201505241946'
    }

//    // 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.5.201505241946'
}
// Generate a global code codeverage report
task coverageReport {
  dependsOn subprojects*.test
  def outputPath = "build/reports/coverage"
  inputs.dir subprojects.collect { p -> "${p.buildDir.path}/jacoco" }
  outputs.dir outputPath
  doLast {
    def coveredProjects = subprojects.findAll { p -> new File( "${p.buildDir.path}/jacoco" ).exists() }
    def coreProjects = coveredProjects.findAll { p -> p.name.startsWith('org.apache.zest.core' ) }
    def libProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.apache.zest.lib' ) }
    def extProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.apache.zest.ext' ) }
    def toolsProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.apache.zest.tool' ) }
    def tutoProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.apache.zest.tuto' ) }
    def samplesProjects = coveredProjects.findAll { p -> p.name.startsWith( 'org.apache.zest.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"
      }
    }
  }
}
check.dependsOn coverageReport


// 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.apache.zest.core' ) && !project.name.startsWith( 'org.apache.zest.core.runtime' ) ) ||
    project.name.startsWith( 'org.apache.zest.library' ) ||
    project.name.startsWith( 'org.apache.zest.extension' ) ||
    project.name.startsWith( 'org.apache.zest.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.apache.zest.api", "org.apache.zest.api.*", "org.apache.zest.io", "org.apache.zest.functional" ],
                         "Core Bootstrap": [ "org.apache.zest.bootstrap", "org.apache.zest.bootstrap.*" ],
                         "Core SPI": [ "org.apache.zest.spi", "org.apache.zest.spi.*" ],
                         "Libraries": [ "org.apache.zest.library.*" ],
                         "Extensions": [ "org.apache.zest.valueserialization.*", "org.apache.zest.entitystore.*", "org.apache.zest.index.*", "org.apache.zest.metrics.*", "org.apache.zest.cache.*", "org.apache.zest.migration", "org.apache.zest.migration.*" ],
                         "Tools": [ "org.apache.zest.tools.*", "org.apache.zest.envisage", "org.apache.zest.envisage.*" ],
                         "Test Support": [ "org.apache.zest.test", "org.apache.zest.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.apache.zest.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.apache.zest</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.apache.zest' ) ) {
        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.apache.zest' ) ) {
        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.apache.zest' ) ) {
        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.apache.zest.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.11'
}
