/*
 * Copyright (C) 2017 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.
 */
// TO debug processor, run:
//./gradlew :r:in:k:clean :r:in:k:cC --no-daemon
// -Dorg.gradle.debug=true
// -Dkotlin.compiler.execution.strategy="in-process"

import com.google.devtools.ksp.gradle.KspTask

plugins {
    id("AndroidXPlugin")
    id("com.android.application")
    id("kotlin-android")
    // both ksp and kapt are applied. each run in their own variant.
    id("com.google.devtools.ksp")
    id("kotlin-kapt")
}
android {
    buildFeatures {
        buildConfig = true
    }
    defaultConfig {
        multiDexEnabled true
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [
                        "room.schemaLocation"  : "$projectDir/schemas".toString()
                ]
            }
        }
    }

    sourceSets {
        androidTestWithKapt.assets.srcDirs += files("$projectDir/schemas".toString())
        androidTestWithKspGenJava.assets.srcDirs += files("$projectDir/schemas-ksp".toString())
        androidTestWithKspGenKotlin.assets.srcDirs += files("$projectDir/schemas-ksp".toString())
    }

    flavorDimensions "processorConfiguration"
    productFlavors {
        withKapt {
            dimension "processorConfiguration"
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [
                            "room.schemaLocation"  : "$projectDir/schemas".toString(),
                    ]
                }
            }
        }
        withKspGenJava {
            dimension "processorConfiguration"
        }
        withKspGenKotlin {
            dimension "processorConfiguration"
        }
    }
    namespace "androidx.room.integration.kotlintestapp"
}

dependencies {
    implementation(project(":room:room-common"))
    implementation(project(":room:room-runtime"))
    implementation(project(":room:room-paging"))
    implementation(projectOrArtifact(":arch:core:core-runtime"))
    implementation(projectOrArtifact(":lifecycle:lifecycle-livedata"))
    implementation(projectOrArtifact(":lifecycle:lifecycle-livedata-ktx"))
    implementation(libs.kotlinStdlib)
    implementation(libs.kotlinCoroutinesAndroid)
    implementation(libs.multidex)
    // depend on the shadowed version so that it tests with the shipped artifact
    // this is a temporary attribute until KSP and AndroidX plugin supports variants.
    kspAndroidTestWithKspGenJava(
            project(path: ":room:room-compiler", configuration: "shadowAndImplementation")
    )
    kspAndroidTestWithKspGenKotlin(
            project(path: ":room:room-compiler", configuration: "shadowAndImplementation")
    )
    kaptAndroidTestWithKapt(
            project(path: ":room:room-compiler", configuration: "shadowAndImplementation")
    )
    androidTestImplementation(projectOrArtifact(":lifecycle:lifecycle-livedata-ktx"))
    androidTestImplementation(libs.testExtJunit)
    androidTestImplementation(libs.testCore)
    androidTestImplementation(libs.testRunner) {
        exclude module: "support-annotations"
        exclude module: "hamcrest-core"
    }
    androidTestImplementation(libs.espressoCore, {
        exclude group: "com.android.support", module: "support-annotations"
        exclude module: "hamcrest-core"
    })
    androidTestImplementation(libs.truth)
    androidTestImplementation(libs.kotlinTest)
    androidTestImplementation(project(":room:room-guava"))
    androidTestImplementation(project(":room:room-testing"))
    androidTestImplementation(project(":room:room-paging-guava"))
    androidTestImplementation(project(":room:room-paging-rxjava2"))
    androidTestImplementation(project(":room:room-paging-rxjava3"))
    // we need latest guava android because room-paging-guava's guava-android gets override by
    // its kotlinx-coroutines-guava dependency's guava-jre version
    androidTestImplementation(libs.guavaAndroid)
    androidTestImplementation(project(":room:room-rxjava2"))
    androidTestImplementation(project(":room:room-rxjava3"))
    androidTestImplementation(project(":room:room-ktx"))
    androidTestImplementation(project(":internal-testutils-common"))
    androidTestImplementation("androidx.arch.core:core-testing:2.0.1")
    androidTestImplementation("androidx.paging:paging-runtime:3.1.1")
    androidTestImplementation(projectOrArtifact(":lifecycle:lifecycle-runtime-testing"))
    androidTestImplementation(libs.rxjava2)
    androidTestImplementation(libs.kotlinCoroutinesTest)
    testImplementation(libs.mockitoCore4)
}

class RoomSchemaArgProvider implements CommandLineArgumentProvider {

    @InputDirectory
    @PathSensitive(PathSensitivity.RELATIVE)
    File schemaDir

    @Input
    Provider<Boolean> generateKotlin;

    RoomSchemaArgProvider(File schemaDir, Provider<Boolean> generateKotlin) {
        this.schemaDir = schemaDir
        this.generateKotlin = generateKotlin
    }

    @Override
    Iterable<String> asArguments() {
        // Note: If you're using KSP, you should change the line below to return
        // ["room.schemaLocation=${schemaDir.path}"]
        return [
            "room.schemaLocation=" + schemaDir.path,
            "room.generateKotlin=" + generateKotlin.get()
        ]
    }
}

// KSP does not support argument per flavor so for per flavor options we use flavor named tasks.
// See https://github.com/google/ksp/issues/861.
tasks.withType(KspTask).configureEach { kspTask ->
    kspTask.commandLineArgumentProviders.add(
        new RoomSchemaArgProvider(
            new File(projectDir, "schemas-ksp"),
            provider { kspTask.name.contains("GenKotlin") }
        )
    )
}
