import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType

/*
 * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

apply from: rootProject.file("gradle/compile-jvm.gradle")

repositories {
    mavenLocal()
    mavenCentral()
}

sourceSets {
    npmTest {
        kotlin
        compileClasspath += sourceSets.test.runtimeClasspath
        runtimeClasspath += sourceSets.test.runtimeClasspath
    }
    mavenTest {
        kotlin
        compileClasspath += sourceSets.test.runtimeClasspath
        runtimeClasspath += sourceSets.test.runtimeClasspath
    }
    debugAgentTest {
        kotlin
        compileClasspath += sourceSets.test.runtimeClasspath
        runtimeClasspath += sourceSets.test.runtimeClasspath
    }

    coreAgentTest {
        kotlin
        compileClasspath += sourceSets.test.runtimeClasspath
        runtimeClasspath += sourceSets.test.runtimeClasspath
    }
}

compileDebugAgentTestKotlin {
    kotlinOptions {
        freeCompilerArgs += ["-Xallow-kotlin-package"]
    }
}

task npmTest(type: Test) {
    def sourceSet = sourceSets.npmTest
    environment "projectRoot", project.rootDir
    environment "deployVersion", version
    def dryRunNpm = project.properties['dryRun']
    def doRun = dryRunNpm == "true" // so that we don't accidentally publish anything, especially before the test
    onlyIf { doRun }
    if (doRun) { // `onlyIf` only affects execution of the task, not the dependency subtree
        dependsOn(project(':').getTasksByName("publishNpm", true))
    }
    testClassesDirs = sourceSet.output.classesDirs
    classpath = sourceSet.runtimeClasspath
}

task mavenTest(type: Test) {
    def sourceSet = sourceSets.mavenTest
    dependsOn(project(':').getTasksByName("publishToMavenLocal", true))
    testClassesDirs = sourceSet.output.classesDirs
    classpath = sourceSet.runtimeClasspath
    // we can't depend on the subprojects because we need to test the classfiles that are published in the end.
    // also, we can't put this in the `dependencies` block because the resolution would happen before publication.
    def mavenTestClasspathConfiguration = project.configurations.detachedConfiguration(
            project.dependencies.create("org.jetbrains.kotlinx:kotlinx-coroutines-core:$version"),
            project.dependencies.create("org.jetbrains.kotlinx:kotlinx-coroutines-android:$version"))

    mavenTestClasspathConfiguration.attributes {
        attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)
    }

    classpath += mavenTestClasspathConfiguration
}

task debugAgentTest(type: Test) {
    def sourceSet = sourceSets.debugAgentTest
    dependsOn(project(':kotlinx-coroutines-debug').shadowJar)
    jvmArgs ('-javaagent:' + project(':kotlinx-coroutines-debug').shadowJar.outputs.files.getFiles()[0])
    testClassesDirs = sourceSet.output.classesDirs
    classpath = sourceSet.runtimeClasspath
}

task coreAgentTest(type: Test) {
    def sourceSet = sourceSets.coreAgentTest
    dependsOn(project(':kotlinx-coroutines-core').jvmJar)
    jvmArgs ('-javaagent:' + project(':kotlinx-coroutines-core').jvmJar.outputs.files.getFiles()[0])
    testClassesDirs = sourceSet.output.classesDirs
    classpath = sourceSet.runtimeClasspath
}

dependencies {
    testCompile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    testCompile 'junit:junit:4.12'
    npmTestCompile 'org.apache.commons:commons-compress:1.18'
    npmTestCompile 'com.google.code.gson:gson:2.8.5'
    debugAgentTestCompile project(':kotlinx-coroutines-core')
    debugAgentTestCompile project(':kotlinx-coroutines-debug')
    coreAgentTestCompile project(':kotlinx-coroutines-core')
}

compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

check {
    dependsOn([npmTest, mavenTest, debugAgentTest, coreAgentTest])
}
