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

import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.konan.target.HostManager
import org.gradle.util.VersionNumber
import org.jetbrains.dokka.gradle.DokkaTaskPartial
import org.jetbrains.dokka.gradle.DokkaMultiModuleTask

apply plugin: 'jdk-convention'
apply from: rootProject.file("gradle/opt-in.gradle")

def coreModule = "kotlinx-coroutines-core"
// Not applicable for Kotlin plugin
def sourceless = ['kotlinx.coroutines', 'kotlinx-coroutines-bom', 'integration-testing']
def internal = ['kotlinx.coroutines', 'benchmarks', 'integration-testing']
// Not published
def unpublished = internal + ['example-frontend-js', 'android-unit-tests']

buildscript {
    /*
     * These property group is used to build kotlinx.coroutines against Kotlin compiler snapshot.
     * How does it work:
     * When build_snapshot_train is set to true, kotlin_version property is overridden with kotlin_snapshot_version,
     * atomicfu_version is overwritten by TeamCity environment (AFU is built with snapshot and published to mavenLocal
     * as previous step or the snapshot build).
     * Additionally, mavenLocal and Sonatype snapshots are added to repository list and stress tests are disabled.
     * DO NOT change the name of these properties without adapting kotlinx.train build chain.
     */
    def prop = rootProject.properties['build_snapshot_train']
    ext.build_snapshot_train = prop != null && prop != ""
    if (build_snapshot_train) {
        ext.kotlin_version = rootProject.properties['kotlin_snapshot_version']
        if (kotlin_version == null) {
            throw new IllegalArgumentException("'kotlin_snapshot_version' should be defined when building with snapshot compiler")
        }
    }
    ext.native_targets_enabled = rootProject.properties['disable_native_targets'] == null

    // Determine if any project dependency is using a snapshot version
    ext.using_snapshot_version = build_snapshot_train
    rootProject.properties.each { key, value ->
        if (key.endsWith("_version") && value instanceof String && value.endsWith("-SNAPSHOT")) {
            println("NOTE: USING SNAPSHOT VERSION: $key=$value")
            ext.using_snapshot_version = true
        }
    }

    if (using_snapshot_version) {
        repositories {
            mavenLocal()
        }
    }

    repositories {
        mavenCentral()
        maven { url "https://plugins.gradle.org/m2/" }
        maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev" }
        mavenLocal()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
        classpath "org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicfu_version"
        classpath "org.jetbrains.kotlinx:kotlinx-knit:$knit_version"
        classpath "com.moowork.gradle:gradle-node-plugin:$gradle_node_version"
        classpath "org.jetbrains.kotlinx:binary-compatibility-validator:$binary_compatibility_validator_version"

        // JMH plugins
        classpath "com.github.jengelman.gradle.plugins:shadow:5.1.0"
    }

    CacheRedirector.configureBuildScript(buildscript, rootProject)
}
// todo:KLUDGE: Hierarchical project structures are not fully supported in IDEA, enable only for a regular built
if (!Idea.active) {
    ext.set("kotlin.mpp.enableGranularSourceSetsMetadata", "true")
}

// todo:KLUDGE: This is needed to workaround dependency resolution between Java and MPP modules
def configureKotlinJvmPlatform(configuration) {
    configuration.attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)
}

allprojects {
    // the only place where HostManager could be instantiated
    project.ext.hostManager = new HostManager()
    def deployVersion = properties['DeployVersion']
    if (deployVersion != null) version = deployVersion

    if (build_snapshot_train) {
        ext.kotlin_version = rootProject.properties['kotlin_snapshot_version']
        println "Using Kotlin $kotlin_version for project $it"

        def skipSnapshotChecks = rootProject.properties['skip_snapshot_checks'] != null
        if (!skipSnapshotChecks && version != atomicfu_version) {
            throw new IllegalStateException("Current deploy version is $version, but atomicfu version is not overridden ($atomicfu_version) for $it")
        }

        kotlin_version = rootProject.properties['kotlin_snapshot_version']
    }

    if (using_snapshot_version) {
        repositories {
            mavenLocal()
            maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
        }
    }

    ext.unpublished = unpublished

    // This project property is set during nightly stress test
    def stressTest = project.properties['stressTest']

    // Copy it to all test tasks
    tasks.withType(Test) {
        systemProperty 'stressTest', stressTest
    }
}

apply plugin: "binary-compatibility-validator"
apiValidation {
    ignoredProjects += unpublished + ["kotlinx-coroutines-bom"]
    if (build_snapshot_train) {
        ignoredProjects.remove("example-frontend-js")
        ignoredProjects.add("kotlinx-coroutines-core")
    }
    ignoredPackages += "kotlinx.coroutines.internal"
}

// Configure repositories
allprojects {
    repositories {
        /*
         * google should be first in the repository list because some of the play services
         * transitive dependencies was removed from jcenter, thus breaking gradle dependency resolution
         */
        google()
        mavenCentral()
    }
}

// Add dependency to core source sets. Core is configured in kx-core/build.gradle
configure(subprojects.findAll { !sourceless.contains(it.name) && it.name != coreModule }) {
    evaluationDependsOn(":$coreModule")
    def platform = PlatformKt.platformOf(it)
    apply plugin: "kotlin-${platform}-conventions"
    dependencies {
        // See comment below for rationale, it will be replaced with "project" dependency
        api project(":$coreModule")
        // the only way IDEA can resolve test classes
        testImplementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
    }
}

// Configure subprojects with Kotlin sources
configure(subprojects.findAll { !sourceless.contains(it.name) }) {
    // Use atomicfu plugin, it also adds all the necessary dependencies
    apply plugin: 'kotlinx-atomicfu'

    // Configure options for all Kotlin compilation tasks
    tasks.withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile).all {
        kotlinOptions.freeCompilerArgs += optInAnnotations.collect { "-Xopt-in=" + it }
        kotlinOptions.freeCompilerArgs += "-progressive"
        // Disable KT-36770 for RxJava2 integration
        kotlinOptions.freeCompilerArgs += "-XXLanguage:-ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated"
        // Remove null assertions to get smaller bytecode on Android
        kotlinOptions.freeCompilerArgs += ["-Xno-param-assertions", "-Xno-receiver-assertions", "-Xno-call-assertions"]
    }
}

if (build_snapshot_train) {
    println "Hacking test tasks, removing stress and flaky tests"
    allprojects {
        tasks.withType(Test).all {
            exclude '**/*LinearizabilityTest*'
            exclude '**/*LFTest*'
            exclude '**/*StressTest*'
            exclude '**/*scheduling*'
            exclude '**/*Timeout*'
            exclude '**/*definitely/not/kotlinx*'
            // Disable because of KT-11567 in 1.4
            exclude '**/*CasesPublicAPITest*'
            // Kotlin
            exclude '**/*PrecompiledDebugProbesTest*'
        }
    }

    println "Manifest of kotlin-compiler-embeddable.jar for coroutines"
    configure(subprojects.findAll { it.name == "kotlinx-coroutines-core" }) {
        configurations.matching { it.name == "kotlinCompilerClasspath" }.all {
            resolvedConfiguration.getFiles().findAll { it.name.contains("kotlin-compiler-embeddable") }.each {
                def manifest = zipTree(it).matching {
                    include 'META-INF/MANIFEST.MF'
                }.getFiles().first()

                manifest.readLines().each {
                    println it
                }
            }
        }
    }
}

// Redefine source sets because we are not using 'kotlin/main/fqn' folder convention
configure(subprojects.findAll {
    !sourceless.contains(it.name) &&
            it.name != "benchmarks" &&
            it.name != coreModule &&
            it.name != "example-frontend-js"
}) {
    // Pure JS and pure MPP doesn't have this notion and are configured separately
    // TODO detect it via platformOf and migrate benchmarks to the same scheme
    sourceSets {
        main.kotlin.srcDirs = ['src']
        test.kotlin.srcDirs = ['test']
        main.resources.srcDirs = ['resources']
        test.resources.srcDirs = ['test-resources']
    }
}

def core_docs_url = "https://kotlin.github.io/kotlinx.coroutines/$coreModule/"
def core_docs_file = "$projectDir/kotlinx-coroutines-core/build/dokka/htmlPartial/package-list"
apply plugin: "org.jetbrains.dokka"

configure(subprojects.findAll { !unpublished.contains(it.name) }) {
    if (it.name != 'kotlinx-coroutines-bom') {
        apply from: rootProject.file('gradle/dokka.gradle.kts')
    }
    apply from: rootProject.file('gradle/publish.gradle')
}

configure(subprojects.findAll { !unpublished.contains(it.name) }) {
    if (it.name != "kotlinx-coroutines-bom") {
        if (it.name != coreModule) {
            tasks.withType(DokkaTaskPartial.class) {
                dokkaSourceSets.configureEach {
                    externalDocumentationLink {
                        url.set(new URL(core_docs_url))
                        packageListUrl.set(new File(core_docs_file).toURI().toURL())
                    }
                }
            }
        }
    }
}

// Report Kotlin compiler version when building project
println("Using Kotlin compiler version: $org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION")

// --------------- Cache redirector ---------------

allprojects {
    CacheRedirector.configure(project)
}

// --------------- Configure sub-projects that are published ---------------

def publishTasks = getTasksByName("publish", true) + getTasksByName("publishNpm", true)

task deploy(dependsOn: publishTasks)

apply plugin: 'base'

clean.dependsOn gradle.includedBuilds.collect { it.task(':clean') }

// --------------- Knit configuration ---------------

apply plugin: 'kotlinx-knit'

knit {
    siteRoot = "https://kotlin.github.io/kotlinx.coroutines"
    moduleRoots = [".", "integration", "reactive", "ui"]
    moduleDocs = "build/dokka/htmlPartial"
    dokkaMultiModuleRoot = "build/dokka/htmlMultiModule/"
}

knitPrepare.dependsOn getTasksByName("dokkaHtmlMultiModule", true)

dependencies {
    dokkaHtmlMultiModulePlugin("org.jetbrains.kotlinx:dokka-pathsaver-plugin:$knit_version")
}

// Opt-in for build scan in order to troubleshoot Gradle on TC
if (hasProperty('buildScan')) {
    buildScan {
        termsOfServiceUrl = 'https://gradle.com/terms-of-service'
        termsOfServiceAgree = 'yes'
    }
}

/*
 * kotlinx-coroutines-core dependency leaks into test runtime classpath via kotlin-compiler-embeddable
 * and conflicts with our own test/runtime incompatibilities (e.g. when class is moved from a main to test),
 * so we do substitution here
 */
allprojects { subProject ->
    subProject
            .configurations
            .matching {
                // Excluding substituted project itself because of circular dependencies, but still do it
                // for "*Test*" configurations
                subProject.name != "kotlinx-coroutines-core" || it.name.contains("Test")
            }
            .configureEach { conf ->
                conf.resolutionStrategy.dependencySubstitution {
                    substitute(module("org.jetbrains.kotlinx:kotlinx-coroutines-core"))
                            .using(project(":kotlinx-coroutines-core"))
                            .because("Because Kotlin compiler embeddable leaks coroutines into the runtime classpath, " +
                                    "triggering all sort of incompatible class changes errors")
                }
            }
}
