/*
 * 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 {
    id 'com.github.johnrengelman.shadow' version '1.2.4'
    id "org.jetbrains.kotlin.jvm"
    id 'scala'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

shadowJar {
    zip64 true
}

repositories {
    maven {
        url "https://plugins.gradle.org/m2/"
    }
    mavenCentral()
}

junitPlatform {
    filters {
        engines {
            include 'spek'
        }
    }
}

configurations {
    provided
    compile.extendsFrom provided
}

dependencies {
    compile 'org.scala-lang:scala-library:2.11.8'
    compile group: 'com.github.nscala-time', name: 'nscala-time_2.11', version: '2.2.0'
    compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.9'
    compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.9'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.4'
    compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-kotlin', version: '2.9.8'
    compile group: 'commons-validator', name: 'commons-validator', version: '1.6'

    compile group: 'software.amazon.awssdk', name: 's3', version: '2.6.5'
    compile group: 'software.amazon.awssdk', name: 'kms', version: '2.6.5'


    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    compile "org.jetbrains.kotlin:kotlin-reflect"

    // currently we have to use this specific mesos version to prevent from
    // clashing with spark
    compile('org.apache.mesos:mesos:1.7.0:shaded-protobuf') {
        exclude group: 'com.google.protobuf', module: 'protobuf-java'
    }

    compile('com.jcabi:jcabi-aether:0.10.1') {
        exclude group: 'org.jboss.netty'
    }

    compile('org.apache.activemq:activemq-client:5.15.2') {
        exclude group: 'org.jboss.netty'
    }

    compile('com.uchuhimo:konf:0.11') {
        exclude group: 'org.eclipse.jgit'
    }

    compile group: 'org.apache.maven', name: 'maven-core', version: '3.0.5'
    compile group: 'net.liftweb', name: 'lift-json_2.11', version: '3.2.0'
    
    provided group: 'org.apache.hadoop', name: 'hadoop-yarn-client', version: '2.8.5'
    provided group: 'org.apache.hadoop', name: 'hadoop-common', version: '2.8.5'
    provided group: 'org.apache.hadoop', name: 'hadoop-yarn-api', version: '2.8.5'
    provided group: 'org.apache.hadoop', name: 'hadoop-hdfs', version: '2.8.4'

    testCompile "gradle.plugin.com.github.maiflai:gradle-scalatest:0.14"
    testRuntime 'org.pegdown:pegdown:1.1.0'
    testCompile 'junit:junit:4.11'
    testCompile 'org.scalatest:scalatest_2.11:3.0.1'
    testCompile 'org.scala-lang:scala-library:2.11.8'
    testCompile 'org.jetbrains.spek:spek-api:1.1.5'
    testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
    testRuntime 'org.jetbrains.spek:spek-junit-platform-engine:1.1.5'

    // spek requires kotlin-reflect, can be omitted if already in the classpath
    testRuntimeOnly "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}

task copyToHome() {
}

sourceSets {
    test {
        resources.srcDirs += [file('src/test/resources')]
    }

    // this is done so Scala will compile before Kotlin
    main {
        kotlin {
            srcDirs = ['src/main/kotlin']
        }
        scala {
            srcDirs = ['src/main/kotlin','src/main/java', 'src/main/scala']
        }
        java {
            srcDirs = ['src/main/java']
        }
    }
}

compileKotlin{
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

compileScala {
    dependsOn compileJava
    classpath += files(compileJava.destinationDir) + files(compileKotlin.destinationDir)
}

compileJava {
    dependsOn compileKotlin
}


