/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed 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.
 */

/**
 * This file was created using the `create_project.py` script located in the
 * `<AndroidX root>/development/project-creator` directory.
 *
 * Please use that script when creating a new project, rather than copying an existing project and
 * modifying its settings.
 */


import androidx.build.KotlinTarget
import androidx.build.LibraryType
import androidx.build.PlatformIdentifier
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType

plugins {
    id("AndroidXPlugin")
}

androidXMultiplatform {
    jvm {
        withJava()
    }
    mac()
    linux()
    ios()
    watchos()
    tvos()
    androidNative()
    mingwX64()
    wasmJs()
    js()

    defaultPlatform(PlatformIdentifier.JVM)

    // Source Structure
    //            commonMain
    //    ┌────────────────────────┐
    //    ▼                        ▼
    // jvmMain                nonJvmMain
    //                    ┌────────────────┐
    //                    ▼                ▼
    //                nativeMain        webMain
    //                               ┌───────────┐
    //                               ▼           ▼
    //                             jsMain   wasmJsMain
    sourceSets {
        commonMain {
            dependencies {
                api(libs.kotlinStdlibCommon)
                api(libs.kotlinTestCommon)
            }
        }

        commonTest {
            dependencies {
                implementation(libs.kotlinTestAnnotationsCommon)
            }
        }

        jvmMain {
            dependsOn(commonMain)
            dependencies {
                api(libs.kotlinStdlib)
                api(libs.kotlinTest)
                implementation(libs.guavaAndroid)
                implementation(libs.junit)
            }
        }

        jvmTest {
            dependsOn(commonTest)
            dependencies {
                api(libs.kotlinCoroutinesTest)
            }
        }

        nonJvmMain {
            dependsOn(commonMain)
        }

        nonJvmTest {
            dependsOn(commonTest)
        }

        webMain {
            dependsOn(nonJvmMain)
            dependencies {
                implementation(libs.kotlinTest)
            }
        }
        webTest {
            dependsOn(nonJvmTest)
            dependencies {
                // https://youtrack.jetbrains.com/issue/KT-71032
                implementation("org.jetbrains.kotlin:kotlin-test:2.1.0")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
            }
        }

        jsMain {
            dependsOn(webMain)
        }
        jsTest {
            dependsOn(webTest)
        }

        wasmJsMain {
            dependsOn(webMain)
        }
        wasmJsTest {
            dependsOn(webTest)
        }

        nativeMain {
            dependsOn(nonJvmMain)
        }
        nativeTest {
            dependsOn(nonJvmTest)
        }

        targets.configureEach { target ->
            if (target.platformType == KotlinPlatformType.native) {
                target.compilations["main"].defaultSourceSet {
                    dependsOn(nativeMain)
                }
                target.compilations["test"].defaultSourceSet {
                    dependsOn(nativeTest)
                }
            }
        }

        // Workaround for https://youtrack.jetbrains.com/issue/KT-51763
        // Make sure commonization runs before any compilation task.
        tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile).configureEach {
            it.dependsOn(tasks.named("commonize"))
        }
    }
}

androidx {
    legacyDisableKotlinStrictApiMode = true // Temporarily enabled to allow API tracking
    type = LibraryType.SNAPSHOT_ONLY_TEST_LIBRARY_WITH_API_TASKS // Used to diff against Google Truth
    doNotDocumentReason = "Not shipped externally"
    kotlinTarget = KotlinTarget.KOTLIN_1_9
}
