/*
 * 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 'com.github.maiflai.scalatest' version '0.6-5-g9065d91'
    id 'scala'
    id 'java'
}

shadowJar {
    zip64 true
}

//sourceCompatibility = 1.8
//targetCompatibility = 1.8

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

test {
    maxParallelForks = 1
    forkEvery = 1
}

configurations {
    provided
}

sourceSets {
    main.compileClasspath += configurations.provided
    test.compileClasspath += configurations.provided
    test.runtimeClasspath += configurations.provided
}

dependencies {

    compile group: 'org.scala-lang', name: 'scala-library', version: '2.11.8'
    compile group: 'org.scala-lang', name: 'scala-reflect', version: '2.11.8'
    compile group: 'org.scala-lang', name: 'scala-compiler', version: '2.11.8'
    compile group: 'io.netty', name: 'netty-all', version: '4.0.42.Final'
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.5'
    compile group: 'org.apache.maven', name: 'maven-core', version: '3.0.5'
    compile group: 'org.reflections', name: 'reflections', version: '0.9.10'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.6.5'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.6.5'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.6.5'
    compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-scala_2.11', version: '2.6.5'
    compile group: 'net.liftweb', name: 'lift-json_2.11', version: '3.2.0'

    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 project(':common')
    compile project(':amaterasu-sdk')

    //runtime dependency for spark
    provided('org.apache.spark:spark-repl_2.11:2.2.1')
    provided('org.apache.spark:spark-core_2.11:2.2.1')

    testCompile project(':common')
    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.2'
    testCompile 'org.scala-lang:scala-library:2.11.8'
    testCompile('org.apache.spark:spark-repl_2.11:2.2.1')
    testCompile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.9'

}

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

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

test {

    maxParallelForks = 1
}

task copyToHome(type: Copy) {
    dependsOn shadowJar
    from 'build/libs'
    into '../build/amaterasu/dist'
    from 'build/resources/main'
    into '../build/amaterasu/dist'
}
