// 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()
    }
    dependencies {
        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.7.3'
    }
}
plugins {
    id "org.nosphere.apache.rat" version "0.2.0"
}
allprojects {
    apply plugin: 'eclipse';
    apply plugin: 'idea';
    apply plugin: 'jacoco'
    group = 'apache-wave'
}

//=============================================================================
// 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) {
    compression = Compression.GZIP
    extension = 'tar.gz'
    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() {
    doFirst {
        println ''
        println '--------------------------------------------------------'
        println '        Creating Deployment Source & Binary             '
        println '    Zip and Tar files available in distributions.       '
        println '--------------------------------------------------------'
        println ''
    }
}

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