/*
 * 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.
 */
buildscript {
    ext.kotlin_version = '1.3.21'

    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'org.junit.platform:junit-platform-gradle-plugin:1.1.0'
    }
}

plugins {
    id "org.nosphere.apache.rat" version "0.3.1"
    id "org.jetbrains.kotlin.jvm" version "1.3.0"
    id "distribution"
}

apply plugin: 'distribution'
apply plugin: 'kotlin'
apply plugin: 'project-report'
apply plugin: 'org.junit.platform.gradle.plugin'
htmlDependencyReport {
    projects = project.allprojects
}

allprojects {
    group 'org.apache.amaterasu'
    version '0.2.0-incubating-rc4'
}

task copyLegalFiles(type: Copy) {
    from "./DISCLAIMER", "./LICENSE", "./NOTICE"
    into "${buildDir}/amaterasu"
}

task buildHomeDir() {
    dependsOn subprojects.collect { getTasksByName('copyToHome', true) }
    dependsOn copyLegalFiles
}

task cleanBuild {
    dependsOn clean
    dependsOn buildHomeDir
    buildHomeDir.mustRunAfter(clean)
}

distributions {
    custom {
        baseName = 'apache-amaterasu'
        version = project.version
        contents {
            from { 'build/amaterasu' }
        }
    }
}

task buildDistribution() {
    delete 'build/amaterasu'
    dependsOn buildHomeDir
    dependsOn customDistTar
}

rat {
    // List of exclude directives, defaults to ['**/.gradle/**']
    excludes = ["**/build/**", '**/.gradle/**', '**/gradle/**', '**/.idea/**', '**/.ruby-version/**', '**/repo/**', '**/resources/**',  '**/*.iml/**']
}

tasks.withType(Test) {
    maxParallelForks = 1
}

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"


    testCompile(
            'org.junit.jupiter:junit-jupiter-api:5.2.0'
    )
    testRuntime(
            'org.junit.jupiter:junit-jupiter-engine:5.2.0'
    )

    testImplementation(
            'org.junit.jupiter:junit-jupiter-api:5.2.0'
    )
    testRuntimeOnly(
            'org.junit.jupiter:junit-jupiter-engine:5.2.0',
            'org.junit.vintage:junit-vintage-engine:5.2.0',
            'org.junit.platform:junit-platform-launcher:1.1.0',
            'org.junit.platform:junit-platform-runner:1.1.0'
    )


}


compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = ["-Xjsr305=strict"]
        jvmTarget = "1.8"
    }
}

test {
    useJUnitPlatform()
}