/*
 * 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.plugin.KotlinPlatformType

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

androidXMultiplatform {
    androidLibrary {
        namespace = "androidx.navigation"
        androidResources.enable = true
        // Needed for api tasks and docs generation
        sourceSets {
            androidMain {
                kotlin.srcDirs += 'src/androidMain/java'
            }
        }
    }
    jvmStubs()
    linuxX64Stubs()
//    desktop()
//    mac()
//    linux()
//    ios()

    defaultPlatform(PlatformIdentifier.ANDROID)

    sourceSets {
        commonMain {
            dependencies {
                api(libs.kotlinStdlib)
                api(libs.kotlinCoroutinesCore)
                api(project(":navigation:navigation-common"))
                api("androidx.lifecycle:lifecycle-common:2.8.7")
                api("androidx.lifecycle:lifecycle-runtime:2.8.7")
                api("androidx.lifecycle:lifecycle-viewmodel:2.8.7")

                implementation(libs.kotlinSerializationCore)
                implementation("androidx.collection:collection:1.4.2")
            }
        }
        commonTest {
            dependencies {
                implementation(libs.kotlinTest)
            }
        }
        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("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
                api("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
                api("androidx.activity:activity-ktx:1.7.1")
                api("androidx.core:core-ktx:1.8.0")
                api("androidx.annotation:annotation-experimental:1.4.1")
            }
        }
        androidUnitTest {
            dependsOn(commonTest)
        }
        androidInstrumentedTest {
            dependsOn(commonTest)
            dependencies {
                implementation("androidx.annotation:annotation:1.8.0")
                implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.7")
                implementation("androidx.lifecycle:lifecycle-common:2.8.7")
                implementation("androidx.lifecycle:lifecycle-runtime:2.8.7")
                implementation("androidx.lifecycle:lifecycle-runtime-testing:2.8.7")
                implementation(project(":internal-testutils-navigation"))
                implementation(project(":internal-testutils-runtime"))
                implementation(libs.hamcrestCore)
                implementation(libs.junit)
                implementation(libs.kotlinTest)
                implementation(libs.testCore)
                implementation(libs.testExtJunit)
                implementation(libs.testExtTruth)
                implementation(libs.testMonitor)
                implementation(libs.testRunner)
                implementation(libs.testRules)
                implementation(libs.espressoIntents)
                implementation(libs.truth)
                implementation(libs.dexmakerMockito)
                implementation(libs.mockitoCore)
            }
        }
        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-runtime-lint"))
}

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