/*
 * Copyright (C) 2016 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.SoftwareType
import androidx.build.PlatformIdentifier
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType

plugins {
    id("AndroidXPlugin")
    alias(libs.plugins.kotlinSerialization)
}

androidXMultiplatform {
    androidLibrary {
        namespace = "androidx.navigation.common"
        optimization {
            it.consumerKeepRules.publish = true
            it.consumerKeepRules.files.add(new File("proguard-rules.pro"))
        }
        androidResources.enable = true
    }
    jvmStubs()
    linuxX64Stubs()
//    desktop()
//    mac()
//    linux()
//    ios()

    defaultPlatform(PlatformIdentifier.ANDROID)

    sourceSets {
        configureEach {
            languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
        }

        commonMain {
            dependencies {
                api("androidx.annotation:annotation:1.8.1")
                api("androidx.lifecycle:lifecycle-common:2.9.1")
                api("androidx.lifecycle:lifecycle-runtime:2.9.1")
                api("androidx.lifecycle:lifecycle-viewmodel:2.9.1")
                api("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.9.1")
                api("androidx.savedstate:savedstate:1.3.0")
                api(libs.kotlinStdlib)
                implementation("androidx.collection:collection:1.4.2")
                implementation(libs.kotlinSerializationCore)
            }
        }
        commonTest {
            dependencies {
                implementation(libs.kotlinTest)
                implementation(project(":kruth:kruth"))
            }
        }

        nonAndroidMain {
            dependsOn(commonMain)
        }
        nonAndroidTest {
            dependsOn(commonTest)
        }
        jvmCommonMain {
            dependsOn(commonMain)
        }
        jvmCommonTest {
            dependsOn(commonTest)
        }
        jvmStubsMain {
            dependsOn(jvmCommonMain)
            dependsOn(nonAndroidMain)
        }
        jvmStubsTest {
            dependsOn(jvmCommonTest)
            dependsOn(nonAndroidTest)
        }
//        desktopMain {
//            dependsOn(jvmCommonMain)
//            dependsOn(nonAndroidMain)
//        }
//        desktopTest {
//            dependsOn(jvmCommonTest)
//            dependsOn(nonAndroidTest)
//        }
        androidMain {
            dependsOn(jvmCommonMain)
            dependencies {
                api(project(":lifecycle:lifecycle-runtime"))
                api(project(":lifecycle:lifecycle-viewmodel"))
                api(project(":savedstate:savedstate-ktx"))
                implementation("androidx.core:core-ktx:1.1.0")
                implementation("androidx.profileinstaller:profileinstaller:1.4.0")
            }
        }

        androidUnitTest {
            dependsOn(commonTest)
            dependencies {
                implementation(project(":navigation:navigation-testing"))
                implementation("androidx.arch.core:core-testing:2.2.0")
                implementation(libs.junit)
                implementation(libs.mockitoCore4)
                implementation(libs.truth)
                implementation(libs.kotlinCoroutinesCore)
                implementation(libs.kotlinCoroutinesTest)
                runtimeOnly(libs.kotlinTestJunit)
                runtimeOnly(libs.testCore)
            }
        }

        androidInstrumentedTest {
            dependsOn(commonTest)
            dependencies {
                implementation(libs.junit)
                implementation(libs.testExtJunit)
                implementation(libs.testRunner)
                implementation(libs.truth)
                implementation(libs.mockitoCore)
                implementation(libs.dexmakerMockito)
            }
        }

        nonJvmCommonMain { dependsOn(nonAndroidMain) }

        nonJvmCommonTest { dependsOn(nonAndroidTest) }

        nativeMain { dependsOn(nonJvmCommonMain) }
        linuxMain { dependsOn(nativeMain) }
//        darwinMain { dependsOn(nativeMain) }
//
        nativeTest { dependsOn(nonJvmCommonTest) }
        linuxTest { dependsOn(nativeTest) }
//        darwinTest { dependsOn(nativeTest) }
//
        targets.configureEach { target ->
            if (target.platformType == KotlinPlatformType.native) {
//                if (target.konanTarget.family.appleFamily) {
//                    target.compilations["main"].defaultSourceSet.dependsOn(darwinMain)
//                    target.compilations["test"].defaultSourceSet.dependsOn(darwinTest)
//                } else
                if (target.konanTarget.family == org.jetbrains.kotlin.konan.target.Family.LINUX) {
                    target.compilations["main"].defaultSourceSet.dependsOn(linuxMain)
                    target.compilations["test"].defaultSourceSet.dependsOn(linuxTest)
                }
            }
        }
        linuxx64StubsMain.dependsOn(linuxMain)
        linuxx64StubsTest.dependsOn(linuxTest)
    }
}

dependencies {
    lintPublish(project(":navigation:navigation-common-lint"))
}

androidx {
    name = "Navigation Common"
    type = SoftwareType.PUBLISHED_LIBRARY
    inceptionYear = "2017"
    description = "Android Navigation-Common"
}
