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


import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.dokka.gradle.DokkaTaskPartial

import static Projects.*

apply plugin: 'jdk-convention'

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/" }
        CommunityProjectsBuild.addDevRepositoryIfEnabled(delegate, project)
        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.github.node-gradle:gradle-node-plugin:$gradle_node_version"
        classpath "org.jetbrains.kotlinx:binary-compatibility-validator:$binary_compatibility_validator_version"
        classpath "ru.vyarus:gradle-animalsniffer-plugin:1.5.4" // Android API check
        classpath "org.jetbrains.kotlin:atomicfu:$kotlin_version"
        classpath "org.jetbrains.kotlinx:kover-gradle-plugin:$kover_version"

        // JMH plugins
        classpath "gradle.plugin.com.github.johnrengelman:shadow:7.1.2"
    }

    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)
}

// Configure subprojects with Kotlin sources
apply plugin: "configure-compilation-conventions"

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()
        }
    }

    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"
apply plugin: "base"
apply plugin: "kover-conventions"

apiValidation {
    ignoredProjects += unpublished + ["kotlinx-coroutines-bom"]
    if (build_snapshot_train) {
        ignoredProjects.remove("example-frontend-js")
        ignoredProjects.add(coreModule)
    }
    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()
        CommunityProjectsBuild.addDevRepositoryIfEnabled(delegate, project)
    }
}

// needs to be before evaluationDependsOn due to weird Gradle ordering
apply plugin: "animalsniffer-conventions"

// 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")
    if (isMultiplatform(it)) {
        apply plugin: "kotlin-multiplatform"
        apply from: rootProject.file("gradle/compile-jvm-multiplatform.gradle")
        apply from: rootProject.file("gradle/compile-common.gradle")

        if (rootProject.ext["native_targets_enabled"] as Boolean) {
            apply from: rootProject.file("gradle/compile-native-multiplatform.gradle")
        }

        apply from: rootProject.file("gradle/compile-js-multiplatform.gradle")
        apply from: rootProject.file("gradle/publish-npm-js.gradle")
        kotlin.sourceSets.commonMain.dependencies {
            api project(":$coreModule")
        }
        kotlin.sourceSets.jvmTest.dependencies {
            implementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
        }
    } else {
        def platform = PlatformKt.platformOf(it)
        apply plugin: "kotlin-${platform}-conventions"
        dependencies {
            api project(":$coreModule")
            // the only way IDEA can resolve test classes
            testImplementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
        }
    }
}

apply plugin: "bom-conventions"
apply plugin: "java-modularity-conventions"

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 == coreModule }) {
        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) && !isMultiplatform(it) &&
            it.name != "benchmarks" &&
            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://kotlinlang.org/api/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)
        && it.name != coreModule }) {
    if (it.name != 'kotlinx-coroutines-bom' && it.name != jdk8ObsoleteModule) {
        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 && it.name != jdk8ObsoleteModule) {
            tasks.withType(DokkaTaskPartial.class) {
                dokkaSourceSets.configureEach {
                    externalDocumentationLink {
                        url.set(new URL(core_docs_url))
                        packageListUrl.set(new File(core_docs_file).toURI().toURL())
                    }
                }
            }
        }
    }

    def thisProject = it
    if (thisProject.name in sourceless) {
        return
    }

    def versionFileTask = thisProject.tasks.register("versionFileTask") {
        def name = thisProject.name.replace("-", "_")
        def versionFile = thisProject.layout.buildDirectory.file("${name}.version")
        it.outputs.file(versionFile)

        it.doLast {
            versionFile.get().asFile.text = version.toString()
        }
    }

    List<String> jarTasks
    if (isMultiplatform(it)) {
        jarTasks = ["jvmJar", "metadataJar"]
    } else if (it.name == "kotlinx-coroutines-debug") {
        // We shadow debug module instead of just packaging it
        jarTasks = ["shadowJar"]
    } else {
        jarTasks = ["jar"]
    }

    for (name in jarTasks) {
        thisProject.tasks.named(name, Jar) {
            it.dependsOn versionFileTask
            it.from(versionFileTask) {
                into("META-INF")
            }
        }
    }
}

// Report Kotlin compiler version when building project
println("Using Kotlin compiler version: $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)

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

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

apply plugin: 'kotlinx-knit'

knit {
    siteRoot = "https://kotlinlang.org/api/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 != coreModule || it.name.contains("Test")
            }
            .configureEach { conf ->
                conf.resolutionStrategy.dependencySubstitution {
                    substitute(module("org.jetbrains.kotlinx:$coreModule"))
                            .using(project(":$coreModule"))
                            .because("Because Kotlin compiler embeddable leaks coroutines into the runtime classpath, " +
                                    "triggering all sort of incompatible class changes errors")
                }
            }
}

tasks.named("dokkaHtmlMultiModule") {
    pluginsMapConfiguration.set(["org.jetbrains.dokka.base.DokkaBase": """{ "templatesDir": "${projectDir.toString().replace('\\', '/')}/dokka-templates" }"""])
}

if (CacheRedirector.enabled) {
    def yarnRootExtension = rootProject.extensions.findByType(YarnRootExtension.class)
    if (yarnRootExtension != null) {
        yarnRootExtension.downloadBaseUrl = CacheRedirector.maybeRedirect(yarnRootExtension.downloadBaseUrl)
    }

    def nodeJsExtension = rootProject.extensions.findByType(NodeJsRootExtension.class)
    if (nodeJsExtension != null) {
        nodeJsExtension.nodeDownloadBaseUrl = CacheRedirector.maybeRedirect(nodeJsExtension.nodeDownloadBaseUrl)
    }
}
