/*
 * 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'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

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

dependencies {
    compile 'org.scala-lang:scala-library: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 project(':common')
    compile project(':amaterasu-sdk')

    compile group: 'com.github.scopt', name: 'scopt_2.11', version: '3.3.0'
    compile group: 'com.github.nscala-time', name: 'nscala-time_2.11', version: '2.2.0'
    compile group: 'org.apache.curator', name:'curator-test', version:'2.9.1'
    compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-scala_2.11', version: '2.6.3'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.6.4'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.6.4'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.6.4'
    compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.6.4'
    compile group: 'org.eclipse.jetty', name: 'jetty-plus', version: '9.2.19.v20160908'
    compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.2.19.v20160908'
    compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '9.2.19.v20160908'
    compile group: 'org.eclipse.jetty', name: 'jetty-io', version: '9.2.19.v20160908'
    compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.2.19.v20160908'
    //compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
    compile group: 'org.eclipse.jetty.toolchain', name: 'jetty-test-helper', version: '4.0'
    compile group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '4.2.0.201601211800-r'
    compile group: 'org.yaml', name: 'snakeyaml', version: '1.18'
    compile group: 'commons-cli', name: 'commons-cli', version: '1.2'
    compile group: 'org.jsoup', name: 'jsoup', version: '1.10.2'
    compile group: 'org.scala-lang.modules', name: 'scala-async_2.11', version: '0.9.6'
    compile group: 'org.jsoup', name: 'jsoup', version: '1.10.2'
    compile group: 'org.reflections', name: 'reflections', version: '0.9.11'
    compile group: 'org.apache.activemq', name: 'activemq-broker', version: '5.15.3'
    compile group: 'net.liftweb', name: 'lift-json_2.11', version: '3.2.0'
    runtime group: 'org.apache.activemq', name: 'activemq-kahadb-store', version: '5.15.3'

    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.curator:curator-test:2.9.1'

}


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 copyToHomeRoot(type: Copy) {
    from 'src/main/scripts'
    into '../build/amaterasu/'
}

task copyToHomeBin(type: Copy) {
    dependsOn shadowJar
    from 'build/libs'
    into '../build/amaterasu/bin'
}

task copyToHome() {
    dependsOn copyToHomeRoot
    dependsOn copyToHomeBin
}