/*
 * 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.22'
    id 'scala'
    id 'org.jetbrains.kotlin.jvm'
    id 'java'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

shadowJar {
    zip64 true
}

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 project(':common')
    compile project(':leader-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-framework', version: '2.13.0'
    compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-scala_2.11', version: '2.9.4'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.8'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.8'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
    compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.9.8'
    compile group: 'org.eclipse.jetty', name: 'jetty-plus', version: '9.4.14.v20181114'
    compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.4.14.v20181114'
    compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '9.4.14.v20181114'
    compile group: 'org.eclipse.jetty', name: 'jetty-io', version: '9.4.14.v20181114'
    compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.4.14.v20181114'
    compile group: 'org.eclipse.jetty.toolchain', name: 'jetty-test-helper', version: '4.0'
    compile group: 'org.yaml', name: 'snakeyaml', version: '1.23'
    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: 'net.liftweb', name: 'lift-json_2.11', version: '3.2.0'
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    compile "org.jetbrains.kotlin:kotlin-reflect"

    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.13.0'

}


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

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

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
}

compileKotlin{
    kotlinOptions.jvmTarget = "1.8"
}

compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

compileTestScala {
    dependsOn compileScala
}

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

compileJava {
    dependsOn compileKotlin
}