/*
 * Copyright (C) 2020 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.LibraryType
import androidx.build.KotlinTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("AndroidXPlugin")
    id("kotlin")
}

dependencies {
    api(project(":room:room-compiler-processing"))
    implementation(libs.kotlinStdlibJdk8)
    // For Java source compilation
    implementation(libs.googleCompileTesting)
    // For KSP processing
    implementation(libs.ksp)
    implementation(libs.kspApi)
    implementation(libs.kspCommon)
    implementation(libs.kspEmbeddable)
    // For Kotlin source compilation and KAPT
    implementation(libs.kotlinCompilerEmbeddable)
    implementation(libs.kotlinAnnotationProcessingEmbeddable)
}

/**
 * Create a properties file with versions that can be read from the test helper to setup test projects.
 * see: b/178725084
 */
def writeTestPropsTask = tasks.register("prepareTestConfiguration", WriteProperties.class) {
    description = "Generates a properties file with the current environment for compilation tests"
    destinationFile.set(project.layout.buildDirectory.dir("test-config").map {
        it.file("androidx.room.compiler.processing.util.CompilationTestCapabilities.Config" +
                ".properties")
    })
    property("kotlinVersion", libs.versions.kotlin.get())
    property("kspVersion", libs.versions.ksp.get())
}

java {
    sourceSets {
        main {
            resources.srcDir(
                    writeTestPropsTask.map {
                        it.destinationFile.asFile.get().parentFile
                    }
            )
        }
    }
}

// enable opt in only for tests so that we don't create non experimental APIs by mistake
// in the source.
tasks.named("compileTestKotlin", KotlinCompile.class).configure {
    it.kotlinOptions {
        freeCompilerArgs += [
                "-opt-in=androidx.room.compiler.processing.ExperimentalProcessingApi"
        ]
    }
}

afterEvaluate {
    lint {
        lintOptions {
            // Until fully switch to K2, existing FE1.0 usages are legitimate
            // TODO(b/314151707)
            disable("KotlincFE10")
        }
    }
}

androidx {
    name = "Room XProcessor Testing"
    type = LibraryType.ANNOTATION_PROCESSOR_UTILS
    kotlinTarget = KotlinTarget.KOTLIN_1_9
    inceptionYear = "2020"
    description = "Testing helpers for Room XProcessing APIs"
}
