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

//=============================================================================
// Plugins
//=============================================================================
buildscript {
    repositories {
        mavenCentral()
    }
}
plugins {
    id "org.nosphere.apache.rat" version "0.2.0"
}
allprojects {
    apply plugin: 'eclipse'
    apply plugin: 'idea'
    apply plugin: 'jacoco'
    group = 'apache-wave'
}

tasks.withType(Tar) {
    compression = Compression.BZIP2
}

//=============================================================================
// Project Level Settings
//=============================================================================
version = 0.4 //only applies to the wave server & client, should be changed once split

//=============================================================================
// Apache Rat Configuration
//=============================================================================
rat {
    inputDir = '.'
    reportDir = project.file('reports/rat')
    excludes = [
            '**/build/**',
            'reports/**',
            '.gradle/',
            '.idea/',
            '.vagrant/',
            '**/*.gradle',
            '**/*.iml',
            '**/generated/**'
    ]
    failOnError = false
}
rat.doFirst {
    println ''
    println '----------------------------------------------'
    println '             Checking Licenses                '
    println ' This task can take between 10 to 20 minutes. '
    println '----------------------------------------------'
    println ''
}

//=============================================================================
// Source Distribution
//=============================================================================

def srcName = this.group + "-src-" + this.version
def srcExcludes = [
        'distributions/',
        '.gradle/',
        '.git/',
        '.vagrant/',
        '*/build/*',
        '*/_*',
        '*/gwt-unitCache/',
        '*.iml',
        '*/*.iml',
        '*.iws',
        '*.ipr',
        '*.project',
        '*/*.project',
        '*/*.classpath',
        '*/.settings/',
        '*/*.log*',
        'reports/',
        'wave/war/WEB-INF',
        'wave/war/webclient'
]

task createDistSourceZip(type: Zip) {
    baseName = srcName
    destinationDir = file('distributions')
    from('./') {
        into 'apache-wave-src'
    }
    excludes = srcExcludes
}

task createDistSourceTar(type: Tar) {
    baseName = srcName
    destinationDir = file('distributions')
    from('./') {
        into 'apache-wave-src'
    }
    excludes = srcExcludes
}

task createDistSource() {
    doFirst {
        println ''
        println '--------------------------------------------------------'
        println '             Creating Deployment Source                 '
        println '--------------------------------------------------------'
        println ''
    }
}

createDistSource.dependsOn createDistSourceZip, createDistSourceTar, ":pst:createDistSource"

//=============================================================================
// Distribution's
//=============================================================================
task createDist(type: Copy) {
    doFirst {
        println ''
        println '--------------------------------------------------------'
        println '        Creating Deployment Source & Binary             '
        println '    Zip and Tar files available in distributions.       '
        println '--------------------------------------------------------'
        println ''
    }
    from('wave/build/distributions') {
    }
    into 'distributions'
}

createDist.dependsOn createDistSource, ":wave:assembleDist", ":pst:createDist"