/*
 * Copyright 2018 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.
 */

package androidx.build

import androidx.benchmark.gradle.BenchmarkPlugin
import androidx.build.AndroidXImplPlugin.Companion.TASK_TIMEOUT_MINUTES
import androidx.build.Release.DEFAULT_PUBLISH_CONFIG
import androidx.build.buildInfo.addCreateLibraryBuildInfoFileTasks
import androidx.build.checkapi.AndroidMultiplatformApiTaskConfig
import androidx.build.checkapi.JavaApiTaskConfig
import androidx.build.checkapi.KmpApiTaskConfig
import androidx.build.checkapi.LibraryApiTaskConfig
import androidx.build.checkapi.configureProjectForApiTasks
import androidx.build.docs.CheckTipOfTreeDocsTask.Companion.setUpCheckDocsTask
import androidx.build.gradle.isRoot
import androidx.build.license.configureExternalDependencyLicenseCheck
import androidx.build.resources.CopyPublicResourcesDirTask
import androidx.build.resources.configurePublicResourcesStub
import androidx.build.sbom.configureSbomPublishing
import androidx.build.sbom.validateAllArchiveInputsRecognized
import androidx.build.studio.StudioTask
import androidx.build.testConfiguration.ModuleInfoGenerator
import androidx.build.testConfiguration.TestModule
import androidx.build.testConfiguration.addAppApkToTestConfigGeneration
import androidx.build.testConfiguration.configureTestConfigGeneration
import androidx.build.uptodatedness.TaskUpToDateValidator
import androidx.build.uptodatedness.cacheEvenIfNoOutputs
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.KotlinMultiplatformAndroidTarget
import com.android.build.api.dsl.KotlinMultiplatformAndroidTestOnDeviceCompilation
import com.android.build.api.dsl.KotlinMultiplatformAndroidTestOnJvmCompilation
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.PrivacySandboxSdkExtension
import com.android.build.api.dsl.TestExtension
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.api.variant.HasDeviceTests
import com.android.build.api.variant.HasUnitTestBuilder
import com.android.build.api.variant.KotlinMultiplatformAndroidComponentsExtension
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.android.build.api.variant.Variant
import com.android.build.gradle.AppPlugin
import com.android.build.gradle.LibraryPlugin
import com.android.build.gradle.TestPlugin
import com.android.build.gradle.api.KotlinMultiplatformAndroidPlugin
import com.android.build.gradle.api.PrivacySandboxSdkPlugin
import com.android.build.gradle.tasks.factory.AndroidUnitTest
import com.android.utils.appendCapitalized
import java.io.File
import java.time.Duration
import java.time.LocalDateTime
import java.util.Locale
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.JavaVersion
import org.gradle.api.JavaVersion.VERSION_11
import org.gradle.api.JavaVersion.VERSION_17
import org.gradle.api.JavaVersion.VERSION_1_8
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.CacheableRule
import org.gradle.api.artifacts.ComponentMetadataContext
import org.gradle.api.artifacts.ComponentMetadataRule
import org.gradle.api.artifacts.Configuration
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Zip
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.api.tasks.testing.AbstractTestTask
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.gradle.build.event.BuildEventsListenerRegistry
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.KotlinClosure1
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.findByType
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.withModule
import org.gradle.kotlin.dsl.withType
import org.gradle.plugin.devel.plugins.JavaGradlePluginPlugin
import org.gradle.plugin.devel.tasks.ValidatePlugins
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper
import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile

/**
 * A plugin which enables all of the Gradle customizations for AndroidX. This plugin reacts to other
 * plugins being added and adds required and optional functionality.
 */
abstract class AndroidXImplPlugin
@Inject
constructor(private val componentFactory: SoftwareComponentFactory) : Plugin<Project> {
    @get:javax.inject.Inject abstract val registry: BuildEventsListenerRegistry

    override fun apply(project: Project) {
        if (project.isRoot)
            throw Exception("Root project should use AndroidXRootImplPlugin instead")
        val androidXExtension =
            project.extensions.create<AndroidXExtension>(EXTENSION_NAME, project)

        val androidXKmpExtension =
            project.extensions.create<AndroidXMultiplatformExtension>(
                AndroidXMultiplatformExtension.EXTENSION_NAME,
                project
            )

        project.tasks.register(BUILD_ON_SERVER_TASK, DefaultTask::class.java)
        // Perform different actions based on which plugins have been applied to the project.
        // Many of the actions overlap, ex. API tracking.
        project.plugins.configureEach { plugin ->
            @Suppress("UnstableApiUsage") // PrivacySandboxSdkPlugin, KMPAndroidPlugin
            when (plugin) {
                is JavaGradlePluginPlugin -> configureGradlePluginPlugin(project)
                is JavaPlugin -> configureWithJavaPlugin(project, androidXExtension)
                is LibraryPlugin -> configureWithLibraryPlugin(project, androidXExtension)
                is AppPlugin -> configureWithAppPlugin(project, androidXExtension)
                is TestPlugin -> configureWithTestPlugin(project, androidXExtension)
                is KotlinMultiplatformAndroidPlugin ->
                    configureWithKotlinMultiplatformAndroidPlugin(
                        project,
                        androidXKmpExtension.agpKmpExtension,
                        androidXExtension
                    )
                is KotlinBasePluginWrapper ->
                    configureWithKotlinPlugin(
                        project,
                        androidXExtension,
                        plugin,
                        androidXKmpExtension
                    )
                is PrivacySandboxSdkPlugin -> configureWithPrivacySandboxSdkPlugin(project)
            }
        }

        project.configureLint()
        val formatWithKtfmt =
            project.getKtfmtOptInPathPrefixes().any { prefix -> project.path.startsWith(prefix) }
        if (formatWithKtfmt) {
            project.configureKtfmt()
        } else {
            project.configureKtlint()
        }
        project.configureKotlinVersion()

        // Avoid conflicts between full Guava and LF-only Guava.
        project.configureGuavaUpgradeHandler()

        // Configure all Jar-packing tasks for hermetic builds.
        project.tasks.withType(Zip::class.java).configureEach { it.configureForHermeticBuild() }
        project.tasks.withType(Copy::class.java).configureEach { it.configureForHermeticBuild() }

        val allHostTests = project.tasks.register("allHostTests").get()
        // copy host side test results to DIST
        project.tasks.withType(AbstractTestTask::class.java) { task ->
            configureTestTask(project, task, allHostTests)
        }

        project.tasks.withType(Test::class.java).configureEach { task ->
            configureJvmTestTask(project, task)
        }

        project.configureTaskTimeouts()
        project.configureMavenArtifactUpload(
            androidXExtension,
            androidXKmpExtension,
            componentFactory
        ) {
            project.addCreateLibraryBuildInfoFileTasks(androidXExtension, androidXKmpExtension)
        }
        project.publishInspectionArtifacts()
        project.configureExternalDependencyLicenseCheck()
        project.configureProjectStructureValidation(androidXExtension)
        project.configureProjectVersionValidation(androidXExtension)
        project.registerProjectOrArtifact()
        project.validateMultiplatformPluginHasNotBeenApplied()

        project.tasks.register("printCoordinates", PrintProjectCoordinatesTask::class.java) {
            it.configureWithAndroidXExtension(androidXExtension)
        }
        project.configureConstraintsWithinGroup(androidXExtension)
        project.validateProjectParser(androidXExtension)
        project.validateAllArchiveInputsRecognized()
        project.afterEvaluate {
            if (androidXExtension.shouldPublishSbom()) {
                project.configureSbomPublishing()
            }
            if (androidXExtension.shouldPublish()) {
                project.validatePublishedMultiplatformHasDefault()
            }
            project.registerValidateMultiplatformSourceSetNamingTask()
        }
        project.disallowAccidentalAndroidDependenciesInKmpProject(androidXKmpExtension)
        TaskUpToDateValidator.setup(project, registry)

        project.workaroundPrebuiltTakingPrecedenceOverProject()
        project.configureSamplesProject()
    }

    private fun Project.registerProjectOrArtifact() {
        // Add a method for each sub project where they can declare an optional
        // dependency on a project or its latest snapshot artifact.
        if (!ProjectLayoutType.isPlayground(this)) {
            // In AndroidX build, this is always enforced to the project
            extra.set(
                PROJECT_OR_ARTIFACT_EXT_NAME,
                KotlinClosure1<String, Project>(
                    function = {
                        // this refers to the first parameter of the closure.
                        project.resolveProject(this)
                    }
                )
            )
        } else {
            // In Playground builds, they are converted to the latest SNAPSHOT artifact if the
            // project is not included in that playground.
            extra.set(
                PROJECT_OR_ARTIFACT_EXT_NAME,
                KotlinClosure1<String, Any>(
                    function = {
                        AndroidXPlaygroundRootImplPlugin.projectOrArtifact(rootProject, this)
                    }
                )
            )
        }
    }

    /**
     * Disables timestamps and ensures filesystem-independent archive ordering to maximize
     * cross-machine byte-for-byte reproducibility of artifacts.
     */
    private fun Zip.configureForHermeticBuild() {
        isReproducibleFileOrder = true
        isPreserveFileTimestamps = false
    }

    private fun Copy.configureForHermeticBuild() {
        duplicatesStrategy = DuplicatesStrategy.FAIL
    }

    private fun configureJvmTestTask(project: Project, task: Test) {
        // Robolectric 1.7 increased heap size requirements, see b/207169653.
        task.maxHeapSize = "3g"

        // For non-playground setup use robolectric offline
        if (!ProjectLayoutType.isPlayground(project)) {
            task.systemProperty("robolectric.offline", "true")
            val robolectricDependencies =
                File(
                    project.getPrebuiltsRoot(),
                    "androidx/external/org/robolectric/android-all-instrumented"
                )
            task.systemProperty(
                "robolectric.dependency.dir",
                robolectricDependencies.relativeTo(project.projectDir)
            )
        }
    }

    private fun configureTestTask(
        project: Project,
        task: AbstractTestTask,
        anchorTask: Task,
    ) {
        anchorTask.dependsOn(task)
        val ignoreFailuresProperty =
            project.providers.gradleProperty(TEST_FAILURES_DO_NOT_FAIL_TEST_TASK)
        val ignoreFailures = ignoreFailuresProperty.isPresent
        if (ignoreFailures) {
            task.ignoreFailures = true
        }
        task.inputs.property("ignoreFailures", ignoreFailures)

        val xmlReportDestDir = project.getHostTestResultDirectory()
        val testName = "${project.path}:${task.name}"
        project.rootProject.tasks.named("createModuleInfo").configure {
            it as ModuleInfoGenerator
            it.testModules.add(
                TestModule(
                    name = testName,
                    path =
                        listOf(project.projectDir.toRelativeString(project.getSupportRootFolder()))
                )
            )
        }
        val archiveName = "$testName.zip"
        if (project.isDisplayTestOutput()) {
            // Enable tracing to see results in command line
            task.testLogging.apply {
                events =
                    hashSetOf(TestLogEvent.FAILED, TestLogEvent.SKIPPED, TestLogEvent.STANDARD_OUT)
                showExceptions = true
                showCauses = true
                showStackTraces = true
                exceptionFormat = TestExceptionFormat.FULL
            }
        } else {
            task.testLogging.apply {
                showExceptions = false
                // Disable all output, including the names of the failing tests, by specifying
                // that the minimum granularity we're interested in is this very high number
                // (which is higher than the current maximum granularity that Gradle offers (3))
                minGranularity = 1000
            }
            val testTaskName = task.name
            val capitalizedTestTaskName =
                testTaskName.replaceFirstChar {
                    if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
                }
            val xmlReport = task.reports.junitXml
            if (xmlReport.required.get()) {
                val zipXmlTask =
                    project.tasks.register(
                        "zipXmlResultsOf$capitalizedTestTaskName",
                        Zip::class.java
                    ) {
                        it.destinationDirectory.set(xmlReportDestDir)
                        it.archiveFileName.set(archiveName)
                        it.from(project.file(xmlReport.outputLocation))
                        it.include("*.xml")
                    }
                task.finalizedBy(zipXmlTask)
            }
        }
    }

    /** Configures the project to use the Kotlin version specified by `androidx.kotlinTarget`. */
    private fun Project.configureKotlinVersion() {
        val kotlinVersionStringProvider = androidXConfiguration.kotlinBomVersion
        val kotlinTestVersionStringProvider = androidXConfiguration.kotlinTestBomVersion

        // Resolve unspecified Kotlin versions to the target version.
        configurations.configureEach { configuration ->
            val useVersionStringProvider =
                if (configuration.isTest()) {
                    kotlinTestVersionStringProvider
                } else {
                    kotlinVersionStringProvider
                }
            configuration.resolutionStrategy { strategy ->
                strategy.eachDependency { details ->
                    if (
                        details.requested.group == "org.jetbrains.kotlin" &&
                            details.requested.version == null
                    ) {
                        details.useVersion(useVersionStringProvider.get())
                    }
                }
            }
        }

        fun Provider<String>.toKotlinVersionProvider() = map { version ->
            KotlinVersion.fromVersion(version.substringBeforeLast('.'))
        }

        fun KotlinCompilationTask<*>.isTestCompilation() =
            multiplatformExtension?.targets?.any { target ->
                target.compilations.findByName("test")?.compileKotlinTaskName == name
            } ?: false

        // Set the Kotlin compiler's API and language version to ensure bytecode is compatible.
        val kotlinVersionProvider = kotlinVersionStringProvider.toKotlinVersionProvider()
        val kotlinTestVersionProvider = kotlinTestVersionStringProvider.toKotlinVersionProvider()
        tasks.configureEach { task ->
            if (task is KotlinCompilationTask<*>) {
                // We can't directly determine if a Task is compiling test code, but we can scrape
                // the names of all the compilation units and compare them to Task names.
                val useVersionProvider =
                    if (task.isTestCompilation()) {
                        kotlinTestVersionProvider
                    } else {
                        kotlinVersionProvider
                    }
                task.compilerOptions.apiVersion.set(useVersionProvider)
                task.compilerOptions.languageVersion.set(useVersionProvider)
            }
        }

        // Specify coreLibrariesVersion for consumption by Kotlin Gradle Plugin. Note that KGP does
        // not explicitly support varying the version between tasks/configurations for a given
        // project, so this is not strictly correct. Picking the non-test (e.g. lower) value seems
        // to work, though.
        afterEvaluate { evaluatedProject ->
            evaluatedProject.kotlinExtensionOrNull?.let { kotlinExtension ->
                kotlinExtension.coreLibrariesVersion = kotlinVersionStringProvider.get()
            }
        }

        // Resolve classpath conflicts caused by kotlin-stdlib-jdk7 and -jdk8 artifacts by amending
        // the kotlin-stdlib artifact metadata to add same-version constraints.
        project.dependencies {
            components { componentMetadata ->
                componentMetadata.withModule<KotlinStdlibDependenciesRule>(
                    "org.jetbrains.kotlin:kotlin-stdlib"
                )
            }
        }
    }

    @CacheableRule
    internal abstract class KotlinStdlibDependenciesRule : ComponentMetadataRule {
        override fun execute(context: ComponentMetadataContext) {
            val module = context.details.id
            val version = module.version
            context.details.allVariants { variantMetadata ->
                variantMetadata.withDependencyConstraints { constraintsMetadata ->
                    val reason = "${module.name} is in atomic group ${module.group}"
                    constraintsMetadata.add("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$version") {
                        it.because(reason)
                    }
                    constraintsMetadata.add("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version") {
                        it.because(reason)
                    }
                }
            }
        }
    }

    private fun configureWithKotlinPlugin(
        project: Project,
        androidXExtension: AndroidXExtension,
        plugin: KotlinBasePluginWrapper,
        androidXMultiplatformExtension: AndroidXMultiplatformExtension
    ) {
        project.afterEvaluate {
            val targetsAndroid =
                project.plugins.hasPlugin(LibraryPlugin::class.java) ||
                    project.plugins.hasPlugin(AppPlugin::class.java) ||
                    project.plugins.hasPlugin(TestPlugin::class.java) ||
                    @Suppress("UnstableApiUsage")
                    project.plugins.hasPlugin(KotlinMultiplatformAndroidPlugin::class.java)
            val defaultJavaTargetVersion =
                getDefaultTargetJavaVersion(androidXExtension.type).toString()
            if (plugin is KotlinMultiplatformPluginWrapper) {
                project.extensions.getByType<KotlinMultiplatformExtension>().apply {
                    targets.withType<KotlinAndroidTarget> {
                        compilations.configureEach {
                            it.kotlinOptions.jvmTarget = defaultJavaTargetVersion
                        }
                    }
                    targets.withType<KotlinJvmTarget> {
                        val defaultJavaTargetVersionForNonAndroidTargets =
                            getDefaultTargetJavaVersion(
                                    libraryType = androidXExtension.type,
                                    projectName = project.name,
                                    targetName = name
                                )
                                .toString()
                        compilations.configureEach {
                            it.compileJavaTaskProvider?.configure { javaCompile ->
                                javaCompile.targetCompatibility =
                                    defaultJavaTargetVersionForNonAndroidTargets
                                javaCompile.sourceCompatibility =
                                    defaultJavaTargetVersionForNonAndroidTargets
                            }
                            it.kotlinOptions {
                                jvmTarget = defaultJavaTargetVersionForNonAndroidTargets
                                // Set jdk-release version for non-Android KMP targets
                                freeCompilerArgs +=
                                    listOf(
                                        "-Xjdk-release=$defaultJavaTargetVersionForNonAndroidTargets",
                                    )
                            }
                        }
                    }
                }
            } else {
                project.tasks.withType(KotlinJvmCompile::class.java).configureEach { task ->
                    task.kotlinOptions.jvmTarget = defaultJavaTargetVersion
                    if (!targetsAndroid) {
                        // Set jdk-release version for non-Android JVM projects
                        task.kotlinOptions.freeCompilerArgs +=
                            listOf(
                                "-Xjdk-release=$defaultJavaTargetVersion",
                            )
                    }
                }
            }
            project.tasks.withType(KotlinCompile::class.java).configureEach { task ->
                val kotlinCompilerArgs =
                    mutableListOf(
                        "-Xskip-metadata-version-check",
                    )
                // TODO (b/259578592): enable -Xjvm-default=all for camera-camera2-pipe projects
                if (!project.name.contains("camera-camera2-pipe")) {
                    kotlinCompilerArgs += "-Xjvm-default=all"
                }
                if (androidXExtension.type.targetsKotlinConsumersOnly) {
                    // The Kotlin Compiler adds intrinsic assertions which are only relevant
                    // when the code is consumed by Java users. Therefore we can turn this off
                    // when code is being consumed by Kotlin users.

                    // Additional Context:
                    // https://github.com/JetBrains/kotlin/blob/master/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt#L239
                    // b/280633711
                    kotlinCompilerArgs +=
                        listOf(
                            "-Xno-param-assertions",
                            "-Xno-call-assertions",
                            "-Xno-receiver-assertions"
                        )
                }
                task.kotlinOptions.freeCompilerArgs += kotlinCompilerArgs
                logScriptSources(task, project)
            }

            val kotlinExtension = project.extensions.getByType(KotlinProjectExtension::class.java)
            kotlinExtension.explicitApi =
                if (androidXExtension.shouldEnforceKotlinStrictApiMode()) {
                    ExplicitApiMode.Strict
                } else {
                    ExplicitApiMode.Disabled
                }
        }
        if (plugin is KotlinMultiplatformPluginWrapper) {
            KonanPrebuiltsSetup.configureKonanDirectory(project)
            project.afterEvaluate {
                val libraryExtension = project.extensions.findByType<LibraryExtension>()
                if (libraryExtension != null) {
                    libraryExtension.configureAndroidLibraryWithMultiplatformPluginOptions()
                } else if (!androidXMultiplatformExtension.hasAndroidMultiplatform()) {
                    // Kotlin MPP does not apply java plugin anymore, but we still want to configure
                    // all java-related tasks.
                    // We only need to do this when project does not have Android plugin, which
                    // already
                    // configures Java tasks.
                    configureWithJavaPlugin(project, androidXExtension)
                }
            }
            project.configureKmp()
            project.configureSourceJarForMultiplatform()

            // Disable any source JAR task(s) added by KotlinMultiplatformPlugin.
            // https://youtrack.jetbrains.com/issue/KT-55881
            project.tasks.withType(Jar::class.java).configureEach { jarTask ->
                if (jarTask.name == "jvmSourcesJar") {
                    // We can't set duplicatesStrategy directly on the Jar task since it will get
                    // overridden when the KotlinMultiplatformPlugin creates child specs, but we
                    // can set it on a per-file basis.
                    jarTask.eachFile { fileCopyDetails ->
                        fileCopyDetails.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
                    }
                }
            }
        }
    }

    private fun configureWithAppPlugin(project: Project, androidXExtension: AndroidXExtension) {
        project.extensions.getByType<ApplicationExtension>().apply {
            configureAndroidBaseOptions(project, androidXExtension)
            defaultConfig.targetSdk = project.defaultAndroidConfig.targetSdk
            val debugSigningConfig = signingConfigs.getByName("debug")
            // Use a local debug keystore to avoid build server issues.
            debugSigningConfig.storeFile = project.getKeystore()
            buildTypes.configureEach { buildType ->
                // Sign all the builds (including release) with debug key
                buildType.signingConfig = debugSigningConfig
            }
            configureAndroidApplicationOptions(project, androidXExtension)
            excludeVersionFiles(packaging.resources)
        }

        project.extensions.getByType<ApplicationAndroidComponentsExtension>().apply {
            beforeVariants(selector().withBuildType("release")) { variant ->
                // Cast is needed because ApplicationAndroidComponentsExtension implements both
                // HasUnitTestBuilder and VariantBuilder, and VariantBuilder#enableUnitTest is
                // deprecated in favor of HasUnitTestBuilder#enableUnitTest.
                // Remove the cast when we upgrade to AGP 9.0.0
                (variant as HasUnitTestBuilder).enableUnitTest = false
            }
            onVariants {
                it.configureTests()
                it.configureLocalAsbSigning(project.getKeystore())
            }
        }

        project.buildOnServerDependsOnAssembleRelease()
        project.buildOnServerDependsOnLint()
    }

    private fun configureWithTestPlugin(project: Project, androidXExtension: AndroidXExtension) {
        project.extensions.getByType<TestExtension>().apply {
            configureAndroidBaseOptions(project, androidXExtension)
            defaultConfig.targetSdk = project.defaultAndroidConfig.targetSdk
            val debugSigningConfig = signingConfigs.getByName("debug")
            // Use a local debug keystore to avoid build server issues.
            debugSigningConfig.storeFile = project.getKeystore()
            buildTypes.configureEach { buildType ->
                // Sign all the builds (including release) with debug key
                buildType.signingConfig = debugSigningConfig
            }
            project.configureTestConfigGeneration(this)
            project.addAppApkToTestConfigGeneration(androidXExtension)
            excludeVersionFiles(packaging.resources)
        }

        project.configureJavaCompilationWarnings(androidXExtension)

        project.addToProjectMap(androidXExtension)
    }

    private fun configureWithKotlinMultiplatformAndroidPlugin(
        project: Project,
        kotlinMultiplatformAndroidTarget: KotlinMultiplatformAndroidTarget,
        androidXExtension: AndroidXExtension
    ) {
        val kotlinMultiplatformAndroidComponentsExtension =
            project.extensions.getByType<KotlinMultiplatformAndroidComponentsExtension>()
        kotlinMultiplatformAndroidTarget.configureAndroidBaseOptions(
            project,
            kotlinMultiplatformAndroidComponentsExtension
        )
        kotlinMultiplatformAndroidTarget.configureAndroidLibraryOptions(project, androidXExtension)

        project.configureProjectForApiTasks(AndroidMultiplatformApiTaskConfig, androidXExtension)

        kotlinMultiplatformAndroidComponentsExtension.onVariant { it.configureTests() }

        project.configurePublicResourcesStub(project.multiplatformExtension!!)
        kotlinMultiplatformAndroidComponentsExtension.onVariant { variant ->
            project.configureMultiplatformSourcesForAndroid(
                variant.name,
                kotlinMultiplatformAndroidTarget,
                androidXExtension.samplesProjects
            )
        }
        project.configureVersionFileWriter(project.multiplatformExtension!!, androidXExtension)
        project.configureJavaCompilationWarnings(androidXExtension)

        project.configureDependencyVerification(androidXExtension) { taskProvider ->
            kotlinMultiplatformAndroidTarget.compilations.configureEach {
                taskProvider.configure { task -> task.dependsOn(it.compileTaskProvider) }
            }
        }

        project.addToProjectMap(androidXExtension)
        project.afterEvaluate {
            project.addToBuildOnServer("assembleAndroidMain")
            project.addToBuildOnServer("lint")
        }
        project.setUpCheckDocsTask(androidXExtension)
        project.writeBlankPublicTxtToAar(kotlinMultiplatformAndroidComponentsExtension)
    }

    private fun Project.writeBlankPublicTxtToAar(
        componentsExtension: KotlinMultiplatformAndroidComponentsExtension
    ) {
        val blankPublicResourceDir =
            project.getSupportRootFolder().resolve("buildSrc/blank-res-api")
        componentsExtension.onVariant { variant ->
            val taskProvider =
                tasks.register(
                    "repackageAarWithResourceApi".appendCapitalized(variant.name),
                    RepackagingTask::class.java
                ) { task ->
                    task.from(blankPublicResourceDir)
                    task.from(zipTree(task.aarFile))
                    task.destinationDirectory.fileProvider(
                        task.output.locationOnly.map { location -> location.asFile.parentFile }
                    )
                    task.archiveFileName.set(
                        task.output.locationOnly.map { location -> location.asFile.name }
                    )
                }
            variant.artifacts
                .use(taskProvider)
                .wiredWithFiles(RepackagingTask::aarFile, RepackagingTask::output)
                .toTransform(SingleArtifact.AAR)
        }
    }

    @Suppress("UnstableApiUsage") // usage of PrivacySandboxSdkExtension
    private fun configureWithPrivacySandboxSdkPlugin(project: Project) {
        project.extensions.getByType<PrivacySandboxSdkExtension>().apply {
            configureLocalAsbSigning(experimentalProperties, project.getKeystore())
        }
    }

    private fun configureLocalAsbSigning(
        experimentalProperties: MutableMap<String, Any>,
        keyStore: File
    ) {
        experimentalProperties[ASB_SIGNING_CONFIG_PROPERTY_NAME] = keyStore.absolutePath
    }

    private val ASB_SIGNING_CONFIG_PROPERTY_NAME =
        "android.privacy_sandbox.local_deployment_signing_store_file"

    /** Temporary diagnostics for b/321949384 */
    private fun logScriptSources(task: KotlinCompile, project: Project) {
        if (getBuildId() == "0") return // don't need to log when not running on the build server
        val logFile = File(project.getDistributionDirectory(), "KotlinCompile-scriptSources.log")
        fun writeScriptSources(label: String) {
            val now = LocalDateTime.now()
            @Suppress("INVISIBLE_MEMBER") val scriptSources = task.scriptSources.files
            logFile.appendText(
                "${task.path} $label at $now with ${scriptSources.size} scriptSources: " +
                    "${scriptSources.joinToString()}\n"
            )
        }
        task.doFirst { writeScriptSources("starting") }
        task.doLast { writeScriptSources("completed") }
    }

    /**
     * Excludes files telling which versions of androidx libraries were used in test apks, to avoid
     * invalidating caches as often
     */
    private fun excludeVersionFiles(packaging: com.android.build.api.variant.ResourcesPackaging) {
        packaging.excludes.add("/META-INF/androidx*.version")
    }

    /**
     * Excludes files telling which versions of androidx libraries were used in test apks, to avoid
     * invalidating caches as often
     */
    private fun excludeVersionFiles(packaging: com.android.build.api.dsl.ResourcesPackaging) {
        packaging.excludes.add("/META-INF/androidx*.version")
    }

    private fun Project.buildOnServerDependsOnAssembleRelease() {
        project.addToBuildOnServer("assembleRelease")
    }

    private fun Project.buildOnServerDependsOnLint() {
        if (!project.usingMaxDepVersions()) {
            val androidComponents = extensions.findByType(AndroidComponentsExtension::class.java)
            androidComponents?.onVariants { variant ->
                if (!variant.name.lowercase(Locale.getDefault()).contains("release")) {
                    val taskName =
                        "lint${variant.name.replaceFirstChar {
                            if (it.isLowerCase()) {
                                it.titlecase(Locale.getDefault())
                            } else {
                                it.toString()
                            }
                        }}"
                    project.addToBuildOnServer(taskName)
                }
            }
        }
    }

    @Suppress("UnstableApiUsage") // usage of HasDeviceTests
    private fun HasDeviceTests.configureTests() {
        deviceTests.forEach { deviceTest ->
            deviceTest.packaging.resources.apply {
                excludeVersionFiles(this)

                // Workaround a limitation in AGP that fails to merge these META-INF license files.
                pickFirsts.add("/META-INF/AL2.0")
                // In addition to working around the above issue, we exclude the LGPL2.1 license as
                // we're
                // approved to distribute code via AL2.0 and the only dependencies which pull in
                // LGPL2.1
                // are currently dual-licensed with AL2.0 and LGPL2.1. The affected dependencies
                // are:
                //   - net.java.dev.jna:jna:5.5.0
                excludes.add("/META-INF/LGPL2.1")
            }
        }
    }

    /**
     * Enable long-running method tracing on the UI thread, even if that risks ANR for profiling
     * convenience.
     *
     * See [androidx.build.testConfiguration.INST_ARG_BLOCKLIST], which is used to suppress the arg
     * in CI.
     */
    @Suppress("UnstableApiUsage") // usage of HasDeviceTests
    private fun HasDeviceTests.enableLongMethodTracingInMicrobenchmark(project: Project) {
        if (project.hasBenchmarkPlugin()) {
            deviceTests.forEach { deviceTest ->
                deviceTest.instrumentationRunnerArguments.put(
                    "androidx.benchmark.profiling.skipWhenDurationRisksAnr",
                    "false"
                )
            }
        }
    }

    @Suppress("UnstableApiUsage") // usage of experimentalProperties
    private fun Variant.configureLocalAsbSigning(keyStore: File) {
        experimentalProperties.put(ASB_SIGNING_CONFIG_PROPERTY_NAME, keyStore.absolutePath)
    }

    private fun configureWithLibraryPlugin(project: Project, androidXExtension: AndroidXExtension) {
        project.extensions.getByType<LibraryExtension>().apply {
            publishing { singleVariant(DEFAULT_PUBLISH_CONFIG) }

            configureAndroidBaseOptions(project, androidXExtension)

            // Move to api that allows settings of targetSdk on each variant's androidTest when
            // b/335257447 is fixed
            @Suppress("DEPRECATION")
            defaultConfig.targetSdk = project.defaultAndroidConfig.targetSdk

            val debugSigningConfig = signingConfigs.getByName("debug")
            // Use a local debug keystore to avoid build server issues.
            debugSigningConfig.storeFile = project.getKeystore()
            buildTypes.configureEach { buildType ->
                // Sign all the builds (including release) with debug key
                buildType.signingConfig = debugSigningConfig
            }
            project.configureTestConfigGeneration(this)
            project.addAppApkToTestConfigGeneration(androidXExtension)
        }

        val libraryAndroidComponentsExtension =
            project.extensions.getByType<LibraryAndroidComponentsExtension>()

        libraryAndroidComponentsExtension.apply {
            finalizeDsl {
                // Propagate the compileSdk value into minCompileSdk. Don't propagate
                // compileSdkExtension, since only one library actually depends on the extension
                // APIs and they can explicitly declare that in their build.gradle. Note that when
                // we're using a preview SDK, the value for compileSdk will be null and the
                // resulting AAR metadata won't have a minCompileSdk --
                // this is okay because AGP automatically embeds forceCompileSdkPreview in the AAR
                // metadata and uses it instead of minCompileSdk.
                it.defaultConfig.aarMetadata.minCompileSdk = it.compileSdk
            }
            beforeVariants(selector().withBuildType("release")) { variant ->
                (variant as HasUnitTestBuilder).enableUnitTest = false
            }
            onVariants { variant ->
                variant.configureTests()
                variant.enableLongMethodTracingInMicrobenchmark(project)
            }
        }

        project.disableStrictVersionConstraints()
        project.setPublishProperty(androidXExtension)
        project.configureVersionFileWriter(libraryAndroidComponentsExtension, androidXExtension)
        project.configureJavaCompilationWarnings(androidXExtension)

        val prebuiltLibraries = listOf("libtracing_perfetto.so", "libc++_shared.so")
        val copyPublicResourcesDirTask =
            project.tasks.register(
                "generatePublicResourcesStub",
                CopyPublicResourcesDirTask::class.java
            ) { task ->
                task.buildSrcResDir.set(File(project.getSupportRootFolder(), "buildSrc/res"))
            }
        libraryAndroidComponentsExtension.onVariants { variant ->
            if (variant.buildType == DEFAULT_PUBLISH_CONFIG) {
                // Standard docs, resource API, and Metalava configuration for AndroidX projects.
                project.configureProjectForApiTasks(
                    LibraryApiTaskConfig(variant),
                    androidXExtension
                )
            }
            if (variant.name == DEFAULT_PUBLISH_CONFIG) {
                project.configureSourceJarForAndroid(variant, androidXExtension.samplesProjects)
                project.configureDependencyVerification(androidXExtension) { taskProvider ->
                    taskProvider.configure { task -> task.dependsOn("compileReleaseJavaWithJavac") }
                }
            }
            configurePublicResourcesStub(variant, copyPublicResourcesDirTask)
            val verifyELFRegionAlignmentTaskProvider =
                project.tasks.register(
                    variant.name + "VerifyELFRegionAlignment",
                    VerifyELFRegionAlignmentTask::class.java
                ) { task ->
                    task.files.from(
                        variant.artifacts.get(SingleArtifact.MERGED_NATIVE_LIBS).map { dir ->
                            dir.asFileTree.files
                                .filter { it.extension == "so" }
                                .filter { it.path.contains("arm64-v8a") }
                                .filterNot { prebuiltLibraries.contains(it.name) }
                        }
                    )
                    task.cacheEvenIfNoOutputs()
                }
            project.addToBuildOnServer(verifyELFRegionAlignmentTaskProvider)
        }

        project.setUpCheckDocsTask(androidXExtension)

        project.addToProjectMap(androidXExtension)

        project.buildOnServerDependsOnAssembleRelease()
        project.buildOnServerDependsOnLint()
    }

    private fun configureGradlePluginPlugin(project: Project) {
        project.tasks.withType(ValidatePlugins::class.java).configureEach {
            it.enableStricterValidation.set(true)
            it.failOnWarning.set(true)
        }
        SdkResourceGenerator.generateForHostTest(project)
    }

    private fun getDefaultTargetJavaVersion(
        libraryType: LibraryType,
        projectName: String? = null,
        targetName: String? = null
    ): JavaVersion {
        return when {
            projectName != null && projectName.contains("desktop") -> VERSION_11
            targetName != null && targetName == "desktop" -> VERSION_11
            libraryType == LibraryType.COMPILER_PLUGIN -> VERSION_11
            libraryType.compilationTarget == CompilationTarget.HOST -> VERSION_17
            else -> VERSION_1_8
        }
    }

    private fun configureWithJavaPlugin(project: Project, androidXExtension: AndroidXExtension) {
        project.configureErrorProneForJava()

        // Force Java 1.8 source- and target-compatibility for all Java libraries.
        val javaExtension = project.extensions.getByType<JavaPluginExtension>()
        project.afterEvaluate {
            javaExtension.apply {
                val defaultTargetJavaVersion = getDefaultTargetJavaVersion(androidXExtension.type)
                sourceCompatibility = defaultTargetJavaVersion
                targetCompatibility = defaultTargetJavaVersion
                project.disableJava8TargetObsoleteWarnings()
            }
            if (!project.plugins.hasPlugin(KotlinBasePluginWrapper::class.java)) {
                project.configureSourceJarForJava(androidXExtension.samplesProjects)
            }
        }

        project.configureJavaCompilationWarnings(androidXExtension)

        project.hideJavadocTask()

        project.configureDependencyVerification(androidXExtension) { taskProvider ->
            taskProvider.configure { task ->
                task.dependsOn(project.tasks.named(JavaPlugin.COMPILE_JAVA_TASK_NAME))
            }
        }

        val apiTaskConfig =
            if (project.multiplatformExtension != null) {
                KmpApiTaskConfig
            } else {
                JavaApiTaskConfig
            }

        project.configureProjectForApiTasks(apiTaskConfig, androidXExtension)
        project.setUpCheckDocsTask(androidXExtension)

        project.afterEvaluate {
            if (androidXExtension.shouldRelease()) {
                project.extra.set("publish", true)
            }
        }

        // Workaround for b/120487939 wherein Gradle's default resolution strategy prefers external
        // modules with lower versions over local projects with higher versions.
        project.configurations.configureEach { configuration ->
            configuration.resolutionStrategy.preferProjectModules()
        }

        if (project.multiplatformExtension == null) {
            project.addToBuildOnServer("jar")
        } else {
            val multiplatformExtension = project.multiplatformExtension!!
            multiplatformExtension.targets.forEach {
                if (it.platformType == KotlinPlatformType.jvm) {
                    val task = project.tasks.named(it.artifactsTaskName, Jar::class.java)
                    project.addToBuildOnServer(task)
                }
            }
        }

        project.addToProjectMap(androidXExtension)
    }

    private fun Project.configureProjectStructureValidation(androidXExtension: AndroidXExtension) {
        // AndroidXExtension.mavenGroup is not readable until afterEvaluate.
        afterEvaluate {
            val mavenGroup = androidXExtension.mavenGroup
            val isProbablyPublished =
                androidXExtension.type == LibraryType.PUBLISHED_LIBRARY ||
                    androidXExtension.type ==
                        LibraryType.PUBLISHED_LIBRARY_ONLY_USED_BY_KOTLIN_CONSUMERS ||
                    androidXExtension.type == LibraryType.UNSET
            if (mavenGroup != null && isProbablyPublished && androidXExtension.shouldPublish()) {
                validateProjectMavenGroup(mavenGroup.group)
                validateProjectMavenName(androidXExtension.name.get(), mavenGroup.group)
                validateProjectStructure(mavenGroup.group)
            }
        }
    }

    private fun Project.configureProjectVersionValidation(androidXExtension: AndroidXExtension) {
        // AndroidXExtension.mavenGroup is not readable until afterEvaluate.
        afterEvaluate { androidXExtension.validateMavenVersion() }
    }

    private fun CommonExtension<*, *, *, *, *, *>.configureAndroidBaseOptions(
        project: Project,
        androidXExtension: AndroidXExtension
    ) {
        compileOptions.apply {
            sourceCompatibility = VERSION_1_8
            targetCompatibility = VERSION_1_8
        }
        project.disableJava8TargetObsoleteWarnings()

        val defaultMinSdk = project.defaultAndroidConfig.minSdk
        val defaultCompileSdk = project.defaultAndroidConfig.compileSdk

        // Suppress output of android:compileSdkVersion and related attributes (b/277836549).
        androidResources.additionalParameters += "--no-compile-sdk-metadata"

        compileSdk = project.defaultAndroidConfig.compileSdk

        buildToolsVersion = project.defaultAndroidConfig.buildToolsVersion
        ndkVersion = project.defaultAndroidConfig.ndkVersion

        defaultConfig.minSdk = defaultMinSdk
        defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

        testOptions.animationsDisabled = !project.isMacrobenchmark()
        testOptions.unitTests.isReturnDefaultValues = true
        testOptions.unitTests.all { task -> task.configureForRobolectric() }

        // Include resources in Robolectric tests as a workaround for b/184641296
        testOptions.unitTests.isIncludeAndroidResources = true

        project.afterEvaluate {
            val minSdkVersion = defaultConfig.minSdk!!
            check(minSdkVersion >= defaultMinSdk) {
                "minSdkVersion $minSdkVersion lower than the default of $defaultMinSdk"
            }
            check(compileSdk == defaultCompileSdk || project.isCustomCompileSdkAllowed()) {
                "compileSdk must not be explicitly specified, was \"$compileSdk\""
            }

            project.enforceBanOnVersionRanges()

            if (androidXExtension.type.compilationTarget != CompilationTarget.DEVICE) {
                throw IllegalStateException(
                    "${androidXExtension.type.name} libraries cannot apply the android plugin, as" +
                        " they do not target android devices"
                )
            }
        }

        project.configureErrorProneForAndroid()

        // workaround for b/120487939
        project.configurations.configureEach { configuration ->
            // Gradle seems to crash on androidtest configurations
            // preferring project modules...
            if (!configuration.name.lowercase(Locale.US).contains("androidtest")) {
                configuration.resolutionStrategy.preferProjectModules()
            }
        }

        project.configureFtlRunner(
            project.extensions.getByType(AndroidComponentsExtension::class.java)
        )

        // AGP warns if we use project.buildDir (or subdirs) for CMake's generated
        // build files (ninja build files, CMakeCache.txt, etc.). Use a staging directory that
        // lives alongside the project's buildDir.
        @Suppress("DEPRECATION")
        externalNativeBuild.cmake.buildStagingDirectory =
            File(project.buildDir, "../nativeBuildStaging")

        // Align the ELF region of native shared libs 16kb boundary
        defaultConfig.externalNativeBuild.cmake.arguments.add(
            "-DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,max-page-size=16384"
        )
    }

    private fun KotlinMultiplatformAndroidTarget.configureAndroidBaseOptions(
        project: Project,
        componentsExtension: KotlinMultiplatformAndroidComponentsExtension
    ) {
        val defaultMinSdkVersion = project.defaultAndroidConfig.minSdk
        val defaultCompileSdk = project.defaultAndroidConfig.compileSdk

        compileSdk = defaultCompileSdk
        buildToolsVersion = project.defaultAndroidConfig.buildToolsVersion

        minSdk = defaultMinSdkVersion

        lint.targetSdk = project.defaultAndroidConfig.targetSdk
        compilations
            .withType(KotlinMultiplatformAndroidTestOnDeviceCompilation::class.java)
            .configureEach {
                it.instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
                it.animationsDisabled = true
            }
        compilations
            .withType(KotlinMultiplatformAndroidTestOnJvmCompilation::class.java)
            .configureEach {
                it.isReturnDefaultValues = true
                // Include resources in Robolectric tests as a workaround for b/184641296
                it.isIncludeAndroidResources = true
            }

        project.tasks.withType(AndroidUnitTest::class.java).configureEach { task ->
            task.configureForRobolectric()
        }

        // validate that SDK versions haven't been altered during evaluation
        project.afterEvaluate {
            val minSdkVersion = minSdk!!
            check(minSdkVersion >= defaultMinSdkVersion) {
                "minSdkVersion $minSdkVersion lower than the default of $defaultMinSdkVersion"
            }
            check(compileSdk == defaultCompileSdk || project.isCustomCompileSdkAllowed()) {
                "compileSdk must not be explicitly specified, was \"$compileSdk\""
            }
            project.enforceBanOnVersionRanges()
        }

        project.configureTestConfigGeneration(this, componentsExtension)
        project.configureFtlRunner(componentsExtension)
    }

    private fun KotlinMultiplatformAndroidTarget.configureAndroidLibraryOptions(
        project: Project,
        androidXExtension: AndroidXExtension
    ) {
        // Propagate the compileSdk value into minCompileSdk.
        aarMetadata.minCompileSdk = compileSdk
        project.disableStrictVersionConstraints()
        project.setPublishProperty(androidXExtension)
    }

    /**
     * Adds a module handler replacement rule that treats full Guava (of any version) as an upgrade
     * to ListenableFuture-only Guava. This prevents irreconcilable versioning conflicts and/or
     * class duplication issues.
     */
    private fun Project.configureGuavaUpgradeHandler() {
        // The full Guava artifact is very large, so they split off a special artifact containing a
        // standalone version of the commonly-used ListenableFuture interface. However, they also
        // structured the artifacts in a way that causes dependency resolution conflicts:
        // - `com.google.guava:listenablefuture:1.0` contains only ListenableFuture
        // - `com.google.guava:listenablefuture:9999.0` contains nothing
        // - `com.google.guava:guava` contains all of Guava, including ListenableFuture
        // If a transitive dependency includes `guava` as implementation-type and we have a direct
        // API-type dependency on `listenablefuture:1.0`, then we'll get `listenablefuture:9999.0`
        // on the compilation classpath -- which does not have the ListenableFuture class. However,
        // if we tell Gradle to upgrade all LF dependencies to Guava then we'll get `guava` as an
        // API-type dependency. See b/274621238 for more details.
        project.dependencies {
            modules { moduleHandler ->
                moduleHandler.module("com.google.guava:listenablefuture") { module ->
                    module.replacedBy("com.google.guava:guava")
                }
            }
        }
    }

    private fun Project.disableStrictVersionConstraints() {
        // Gradle inserts strict version constraints to ensure that dependency versions are
        // identical across main and test source sets. For normal projects, this ensures
        // that test bytecode is binary- and behavior-compatible with the main source set's
        // bytecode. For AndroidX, though, we require backward compatibility and therefore
        // don't need to enforce such constraints.
        project.configurations.configureEach { configuration ->
            if (!configuration.isTest()) return@configureEach

            configuration.dependencyConstraints.configureEach { dependencyConstraint ->
                val strictVersion = dependencyConstraint.versionConstraint.strictVersion
                if (strictVersion != "") {
                    // Migrate strict-type version constraints to required-type to allow upgrades.
                    dependencyConstraint.version { versionConstraint ->
                        versionConstraint.strictly("")
                        versionConstraint.require(strictVersion)
                    }
                }
            }
        }
    }

    private fun Project.setPublishProperty(androidXExtension: AndroidXExtension) {
        afterEvaluate {
            if (androidXExtension.shouldRelease()) {
                project.extra.set("publish", true)
            }
        }
    }

    private fun LibraryExtension.configureAndroidLibraryWithMultiplatformPluginOptions() {
        sourceSets.findByName("main")!!.manifest.srcFile("src/androidMain/AndroidManifest.xml")
        sourceSets
            .findByName("androidTest")!!
            .manifest
            .srcFile("src/androidInstrumentedTest/AndroidManifest.xml")
    }

    private fun Project.configureKmp() {
        val kmpExtension =
            checkNotNull(project.extensions.findByType<KotlinMultiplatformExtension>()) {
                """
            Project ${project.path} applies kotlin multiplatform plugin but we cannot find the
            KotlinMultiplatformExtension.
            """
                    .trimIndent()
            }

        kmpExtension.targets.configureEach { kotlinTarget ->
            kotlinTarget.compilations.configureEach { compilation ->
                // Configure all KMP targets to allow expect/actual classes that are not stable.
                // (see https://youtrack.jetbrains.com/issue/KT-61573)
                compilation.compilerOptions.options.freeCompilerArgs.add("-Xexpect-actual-classes")
                androidXConfiguration.kotlinApiVersion.let {
                    compilation.compilerOptions.options.apiVersion.set(it)
                    compilation.compilerOptions.options.languageVersion.set(it)
                }
            }
        }
    }

    private fun ApplicationExtension.configureAndroidApplicationOptions(
        project: Project,
        androidXExtension: AndroidXExtension
    ) {
        defaultConfig.apply {
            versionCode = 1
            versionName = "1.0"
        }

        project.configureTestConfigGeneration(this)
        project.addAppApkToTestConfigGeneration(androidXExtension)
        project.addAppApkToFtlRunner()
    }

    private fun Project.configureDependencyVerification(
        androidXExtension: AndroidXExtension,
        taskConfigurator: (TaskProvider<VerifyDependencyVersionsTask>) -> Unit
    ) {
        afterEvaluate {
            if (androidXExtension.type !in listOf(LibraryType.UNSET, LibraryType.SAMPLES)) {
                val verifyDependencyVersionsTask = project.createVerifyDependencyVersionsTask()
                if (verifyDependencyVersionsTask != null) {
                    taskConfigurator(verifyDependencyVersionsTask)
                }
            }
        }
    }

    // If this project wants other project in the same group to have the same version,
    // this function configures those constraints.
    private fun Project.configureConstraintsWithinGroup(androidXExtension: AndroidXExtension) {
        if (!project.shouldAddGroupConstraints().get()) {
            return
        }
        project.afterEvaluate {
            // make sure that the project has a group
            val projectGroup = androidXExtension.mavenGroup ?: return@afterEvaluate
            // make sure that this group is configured to use a single version
            projectGroup.atomicGroupVersion ?: return@afterEvaluate

            // Under certain circumstances, a project is allowed to override its
            // version see ( isGroupVersionOverrideAllowed ), in which case it's
            // not participating in the versioning policy yet,
            // and we don't assign it any version constraints
            if (androidXExtension.mavenVersion != null) {
                return@afterEvaluate
            }

            // We don't want to emit the same constraint into our .module file more than once,
            // and we don't want to try to apply a constraint to a configuration that doesn't accept
            // them,
            // so we create a configuration to hold the constraints and make each other constraint
            // extend it
            val constraintConfiguration = project.configurations.create("groupConstraints")
            project.configurations.configureEach { configuration ->
                if (configuration != constraintConfiguration)
                    configuration.extendsFrom(constraintConfiguration)
            }

            val otherProjectsInSameGroup = androidXExtension.getOtherProjectsInSameGroup()
            val constraints = project.dependencies.constraints
            val allProjectsExist = buildContainsAllStandardProjects()
            for (otherProject in otherProjectsInSameGroup) {
                val otherGradlePath = otherProject.gradlePath
                if (otherGradlePath == ":compose:ui:ui-android-stubs") {
                    // exemption for library that doesn't truly get published: b/168127161
                    continue
                }
                // We only enable constraints for builds that we intend to be able to publish from.
                //   If a project isn't included in a build we intend to be able to publish from,
                //   the project isn't going to be published.
                // Sometimes this can happen when a project subset is enabled:
                //   The KMP project subset enabled by androidx_multiplatform_mac.sh contains
                //   :benchmark:benchmark-common but not :benchmark:benchmark-benchmark
                //   This is ok because we don't intend to publish that artifact from that build
                val otherProjectShouldExist =
                    allProjectsExist || findProject(otherGradlePath) != null
                if (!otherProjectShouldExist) {
                    continue
                }
                // We only emit constraints referring to projects that will release
                val otherFilepath = File(otherProject.filePath, "build.gradle")
                val parsed = parseBuildFile(otherFilepath)
                if (!parsed.shouldRelease()) {
                    continue
                }
                if (parsed.libraryType == LibraryType.SAMPLES) {
                    // a SAMPLES project knows how to publish, but we don't intend to actually
                    // publish it
                    continue
                }
                // Under certain circumstances, a project is allowed to override its
                // version see ( isGroupVersionOverrideAllowed ), in which case it's
                // not participating in the versioning policy yet and we don't emit
                // version constraints referencing it
                if (parsed.specifiesVersion) {
                    continue
                }
                val dependencyConstraint = project(otherGradlePath)
                constraints.add(constraintConfiguration.name, dependencyConstraint) {
                    it.because("${project.name} is in atomic group ${projectGroup.group}")
                }
            }

            // disallow duplicate constraints
            project.configurations.configureEach { config ->
                // Allow duplicate constraints in test configurations. This is partially a
                // workaround for duplication due to downgrading strict-type dependencies to
                // required-type, but also we don't care if tests have duplicate constraints.
                if (config.isTest()) return@configureEach

                // find all constraints contributed by this Configuration and its ancestors
                val configurationConstraints: MutableSet<String> = mutableSetOf()
                config.hierarchy.forEach { parentConfig ->
                    parentConfig.dependencyConstraints.configureEach { dependencyConstraint ->
                        dependencyConstraint.apply {
                            if (
                                versionConstraint.requiredVersion != "" &&
                                    versionConstraint.requiredVersion != "unspecified"
                            ) {
                                val key =
                                    "${dependencyConstraint.group}:${dependencyConstraint.name}"
                                if (configurationConstraints.contains(key)) {
                                    throw GradleException(
                                        "Constraint on $key was added multiple times in " +
                                            "$config (version = " +
                                            "${versionConstraint.requiredVersion}).\n\n" +
                                            "This is unnecessary and can also trigger " +
                                            "https://github.com/gradle/gradle/issues/24037 in " +
                                            "builds trying to use the resulting artifacts."
                                    )
                                }
                                configurationConstraints.add(key)
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Tells whether this build contains the usual set of all projects (`./gradlew projects`)
     * Sometimes developers request to include fewer projects because this may run more quickly
     */
    private fun Project.buildContainsAllStandardProjects(): Boolean {
        if (getProjectSubset() != null) return false
        if (ProjectLayoutType.isPlayground(this)) return false
        return true
    }

    companion object {
        const val CREATE_LIBRARY_BUILD_INFO_FILES_TASK = "createLibraryBuildInfoFiles"
        const val GENERATE_TEST_CONFIGURATION_TASK = "GenerateTestConfiguration"
        const val FINALIZE_TEST_CONFIGS_WITH_APKS_TASK = "finalizeTestConfigsWithApks"
        const val ZIP_TEST_CONFIGS_WITH_APKS_TASK = "zipTestConfigsWithApks"

        const val TASK_GROUP_API = "API"

        const val EXTENSION_NAME = "androidx"

        /** Fail the build if a non-Studio task runs longer than expected */
        const val TASK_TIMEOUT_MINUTES = 60L
    }
}

private const val PROJECTS_MAP_KEY = "projects"
private const val ACCESSED_PROJECTS_MAP_KEY = "accessedProjectsMap"

/** Returns whether the configuration is used for testing. */
private fun Configuration.isTest(): Boolean = name.lowercase().contains("test")

/**
 * Hides a project's Javadoc tasks from the output of `./gradlew tasks` by setting their group to
 * `null`.
 *
 * AndroidX projects do not use the Javadoc task for docs generation, so we don't want them
 * cluttering up the task overview.
 */
private fun Project.hideJavadocTask() {
    tasks.withType(Javadoc::class.java).configureEach {
        if (it.name == "javadoc") {
            it.group = null
        }
    }
}

private fun Project.addToProjectMap(androidXExtension: AndroidXExtension) {
    // TODO(alanv): Move this out of afterEvaluate
    afterEvaluate {
        if (androidXExtension.shouldRelease()) {
            val group = androidXExtension.mavenGroup?.group
            if (group != null) {
                val module = "$group:$name"

                if (project.rootProject.extra.has(ACCESSED_PROJECTS_MAP_KEY)) {
                    throw GradleException(
                        "Attempted to add $project to project map after " +
                            "the contents of the map were accessed"
                    )
                }
                @Suppress("UNCHECKED_CAST")
                val projectModules =
                    project.rootProject.extra.get(PROJECTS_MAP_KEY)
                        as ConcurrentHashMap<String, String>
                projectModules[module] = path
            }
        }
    }
}

val Project.androidExtension: AndroidComponentsExtension<*, *, *>
    get() =
        extensions.findByType<LibraryAndroidComponentsExtension>()
            ?: extensions.findByType<ApplicationAndroidComponentsExtension>()
            ?: throw IllegalArgumentException("Failed to find any registered Android extension")

val Project.multiplatformExtension
    get() = extensions.findByType(KotlinMultiplatformExtension::class.java)

val Project.kotlinExtensionOrNull: KotlinProjectExtension?
    get() = extensions.findByType()

val Project.androidXExtension: AndroidXExtension
    get() = extensions.getByType()

@Suppress("UNCHECKED_CAST")
fun Project.getProjectsMap(): ConcurrentHashMap<String, String> {
    project.rootProject.extra.set(ACCESSED_PROJECTS_MAP_KEY, true)
    return rootProject.extra.get(PROJECTS_MAP_KEY) as ConcurrentHashMap<String, String>
}

/**
 * Configures all non-Studio tasks in a project (see b/153193718 for background) to time out after
 * [TASK_TIMEOUT_MINUTES].
 */
internal fun Project.configureTaskTimeouts() {
    tasks.configureEach { t ->
        // skip adding a timeout for some tasks that both take a long time and
        // that we can count on the user to monitor
        if (t !is StudioTask) {
            t.timeout.set(Duration.ofMinutes(TASK_TIMEOUT_MINUTES))
        }
    }
}

private fun Project.disableJava8TargetObsoleteWarnings() {
    afterEvaluate {
        project.tasks.withType(JavaCompile::class.java).configureEach { task ->
            // JDK 21 considers Java 8 an obsolete source and target value. Disable this warning.
            task.options.compilerArgs.add("-Xlint:-options")
        }
    }
}

private fun Project.configureJavaCompilationWarnings(androidXExtension: AndroidXExtension) {
    afterEvaluate {
        project.tasks.withType(JavaCompile::class.java).configureEach { task ->
            // If we're running a hypothetical test build confirming that tip-of-tree versions
            // are compatible, then we're not concerned about warnings
            if (!project.usingMaxDepVersions()) {
                task.options.compilerArgs.add("-Xlint:unchecked")
                if (androidXExtension.failOnDeprecationWarnings) {
                    task.options.compilerArgs.add("-Xlint:deprecation")
                }
            }
        }
    }
}

fun Project.hasBenchmarkPlugin(): Boolean {
    return this.plugins.hasPlugin(BenchmarkPlugin::class.java)
}

fun Project.isMacrobenchmark(): Boolean {
    return this.path.endsWith("macrobenchmark")
}

/**
 * Returns a string that is a valid filename and loosely based on the project name The value
 * returned for each project will be distinct
 */
fun String.asFilenamePrefix(): String {
    return this.substring(1).replace(':', '-')
}

/**
 * Sets the specified [task] as a dependency of the top-level `check` task, ensuring that it runs as
 * part of `./gradlew check`.
 */
fun <T : Task> Project.addToCheckTask(task: TaskProvider<T>) {
    project.tasks.named("check").configure { it.dependsOn(task) }
}

fun Project.validateMultiplatformPluginHasNotBeenApplied() {
    if (plugins.hasPlugin(KotlinMultiplatformPluginWrapper::class.java)) {
        throw GradleException(
            "The Kotlin multiplatform plugin should only be applied by the AndroidX plugin."
        )
    }
}

/** Verifies we don't accidentially write "implementation" instead of "commonMainImplementation" */
fun Project.disallowAccidentalAndroidDependenciesInKmpProject(
    androidXKmpExtension: AndroidXMultiplatformExtension
) {
    project.afterEvaluate {
        if (androidXKmpExtension.supportedPlatforms.isNotEmpty()) {
            val androidConfiguration = project.configurations.findByName("implementation")
            if (androidConfiguration != null) {
                if (
                    androidConfiguration.dependencies.isNotEmpty() ||
                        androidConfiguration.dependencyConstraints.isNotEmpty()
                ) {
                    throw GradleException(
                        "The 'implementation' Configuration should not be used in a " +
                            "multiplatform project: this Configuration is declared by the " +
                            "Android plugin rather than the kmp plugin. Did you mean " +
                            "'commonMainImplementation'?"
                    )
                }
            }
        }
    }
}

/** Verifies that ProjectParser computes the correct values for this project */
fun Project.validateProjectParser(androidXExtension: AndroidXExtension) {
    // If configuration fails, we don't want to validate the ProjectParser
    // (otherwise it could report a confusing, unnecessary error)
    project.gradle.taskGraph.whenReady {
        if (!androidXExtension.runProjectParser) return@whenReady

        val parsed = project.parse()
        val errorPrefix = "ProjectParser error parsing ${project.path}."
        check(androidXExtension.type == parsed.libraryType) {
            "$errorPrefix Incorrectly computed libraryType = ${parsed.libraryType} " +
                "instead of ${androidXExtension.type}"
        }
        check(androidXExtension.publish == parsed.publish) {
            "$errorPrefix Incorrectly computed publish = ${parsed.publish} " +
                "instead of ${androidXExtension.publish}"
        }
        check(androidXExtension.shouldPublish() == parsed.shouldPublish()) {
            "$errorPrefix Incorrectly computed shouldPublish() = ${parsed.shouldPublish()} " +
                "instead of ${androidXExtension.shouldPublish()}"
        }
        check(androidXExtension.shouldRelease() == parsed.shouldRelease()) {
            "$errorPrefix Incorrectly computed shouldRelease() = ${parsed.shouldRelease()} " +
                "instead of ${androidXExtension.shouldRelease()}"
        }
        check(androidXExtension.projectDirectlySpecifiesMavenVersion == parsed.specifiesVersion) {
            "$errorPrefix Incorrectly computed specifiesVersion = ${parsed.specifiesVersion} " +
                " instead of ${androidXExtension.projectDirectlySpecifiesMavenVersion}"
        }
    }
}

/** Validates the Maven version against Jetpack guidelines. */
fun AndroidXExtension.validateMavenVersion() {
    val mavenGroup = mavenGroup
    val mavenVersion = mavenVersion
    val forcedVersion = mavenGroup?.atomicGroupVersion
    if (forcedVersion != null && forcedVersion == mavenVersion) {
        throw GradleException(
            """
            Unnecessary override of same-group library version

            Project version is already set to $forcedVersion by same-version group
            ${mavenGroup.group}.

            To fix this error, remove "mavenVersion = ..." from your build.gradle
            configuration.
            """
                .trimIndent()
        )
    }
}

/** Workaround for https://github.com/gradle/gradle/issues/27407 */
fun Project.workaroundPrebuiltTakingPrecedenceOverProject() {
    project.configurations.configureEach { configuration ->
        configuration.resolutionStrategy.preferProjectModules()
    }
}

private fun Test.configureForRobolectric() {
    // https://github.com/robolectric/robolectric/issues/7456
    jvmArgs =
        listOf(
            "--add-opens=java.base/java.lang=ALL-UNNAMED",
            "--add-opens=java.base/java.util=ALL-UNNAMED",
            "--add-opens=java.base/java.io=ALL-UNNAMED",
        )
    // Robolectric 1.7 increased heap size requirements, see b/207169653.
    maxHeapSize = "3g"
}

private fun Project.enforceBanOnVersionRanges() {
    configurations.configureEach { configuration ->
        configuration.resolutionStrategy.eachDependency { dep ->
            val target = dep.target
            val version = target.version
            // Enforce the ban on declaring dependencies with version ranges.
            // Note: In playground, this ban is exempted to allow unresolvable prebuilts
            // to automatically get bumped to snapshot versions via version range
            // substitution.
            if (
                version != null &&
                    Version.isDependencyRange(version) &&
                    project.rootProject.rootDir == project.getSupportRootFolder()
            ) {
                throw IllegalArgumentException(
                    "Dependency ${dep.target} declares its version as " +
                        "version range ${dep.target.version} however the use of " +
                        "version ranges is not allowed, please update the " +
                        "dependency to list a fixed version."
                )
            }
        }
    }
}

internal fun Project.hasAndroidMultiplatformPlugin(): Boolean =
    extensions.findByType(AndroidXMultiplatformExtension::class.java)?.hasAndroidMultiplatform()
        ?: false

internal fun String.camelCase() = replaceFirstChar {
    if (it.isLowerCase()) it.titlecase() else it.toString()
}

const val PROJECT_OR_ARTIFACT_EXT_NAME = "projectOrArtifact"
