/* groovylint-disable LineLength, UnnecessaryGString, UnnecessaryGetter */
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import com.android.build.OutputFile
import groovy.json.JsonGenerator
import groovy.xml.QName
import java.nio.file.Paths
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.Task
import org.gradle.api.file.CopySpec
import org.gradle.api.file.FileCollection
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.bundling.Jar
import org.gradle.internal.os.OperatingSystem

/**
 * For apps only. Provides the flutter extension used in the app-level Gradle
 * build file (app/build.gradle or app/build.gradle.kts).
 *
 * The versions specified here should match the values in
 * packages/flutter_tools/lib/src/android/gradle_utils.dart, so when bumping,
 * make sure to update the versions specified there.
 *
 * Learn more about extensions in Gradle:
 *  * https://docs.gradle.org/8.0.2/userguide/custom_plugins.html#sec:getting_input_from_the_build
*/
class FlutterExtension {

    /** Sets the compileSdkVersion used by default in Flutter app projects. */
    public final int compileSdkVersion = 34

    /** Sets the minSdkVersion used by default in Flutter app projects. */
    public  final int minSdkVersion = 21

    /**
     * Sets the targetSdkVersion used by default in Flutter app projects.
     * targetSdkVersion should always be the latest available stable version.
     *
     * See https://developer.android.com/guide/topics/manifest/uses-sdk-element.
     */
    public final int targetSdkVersion = 34

    /**
     * Sets the ndkVersion used by default in Flutter app projects.
     * Chosen as default version of the AGP version below as found in
     * https://developer.android.com/studio/projects/install-ndk#default-ndk-per-agp.
     */
    public final String ndkVersion = "23.1.7779620"

    /**
     * Specifies the relative directory to the Flutter project directory.
     * In an app project, this is ../.. since the app's Gradle build file is under android/app.
     */
    String source = "../.."

    /** Allows to override the target file. Otherwise, the target is lib/main.dart. */
    String target

    /** The versionCode that was read from app's local.properties. */
    public String flutterVersionCode = null

    /** The versionName that was read from app's local.properties. */
    public String flutterVersionName = null

    /** Returns flutterVersionCode as an integer with error handling. */
    public Integer getVersionCode() {
        if (flutterVersionCode == null) {
            throw new GradleException("flutterVersionCode must not be null.")
        }

        if (!flutterVersionCode.isNumber()) {
            throw new GradleException("flutterVersionCode must be an integer.")
        }

        return flutterVersionCode.toInteger()
    }

    /** Returns flutterVersionName with error handling. */
    public String getVersionName() {
        if (flutterVersionName == null) {
            throw new GradleException("flutterVersionName must not be null.")
        }

        return flutterVersionName
    }

}

// This buildscript block supplies dependencies for this file's own import
// declarations above. It exists solely for compatibility with projects that
// have not migrated to declaratively apply the Flutter Gradle Plugin;
// for those that have, FGP's `build.gradle.kts`  takes care of this.
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        // When bumping, also update:
        //  * ndkVersion in FlutterExtension in packages/flutter_tools/gradle/src/main/groovy/flutter.groovy
        //  * AGP version in the buildscript block in packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts
        //  * AGP version constants in packages/flutter_tools/lib/src/android/gradle_utils.dart
        //  * AGP version in dependencies block in packages/flutter_tools/gradle/build.gradle.kts
        classpath("com.android.tools.build:gradle:7.3.0")
    }
}

/**
 * Some apps don't set default compile options.
 * Apps can change these values in the app-level Gradle build file
 * (android/app/build.gradle or android/app/build.gradle.kts).
 * This just ensures that default values are set.
 */
android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

apply plugin: FlutterPlugin

class FlutterPlugin implements Plugin<Project> {

    private static final String DEFAULT_MAVEN_HOST = "https://storage.googleapis.com"

    /** The platforms that can be passed to the `--Ptarget-platform` flag. */
    private static final String PLATFORM_ARM32  = "android-arm"
    private static final String PLATFORM_ARM64  = "android-arm64"
    private static final String PLATFORM_X86    = "android-x86"
    private static final String PLATFORM_X86_64 = "android-x64"

    /** The ABI architectures supported by Flutter. */
    private static final String ARCH_ARM32      = "armeabi-v7a"
    private static final String ARCH_ARM64      = "arm64-v8a"
    private static final String ARCH_X86        = "x86"
    private static final String ARCH_X86_64     = "x86_64"

    private static final String INTERMEDIATES_DIR = "intermediates"

    /** Maps platforms to ABI architectures. */
    private static final Map PLATFORM_ARCH_MAP = [
        (PLATFORM_ARM32)    : ARCH_ARM32,
        (PLATFORM_ARM64)    : ARCH_ARM64,
        (PLATFORM_X86)      : ARCH_X86,
        (PLATFORM_X86_64)   : ARCH_X86_64,
    ]

    /**
     * The version code that gives each ABI a value.
     * For each APK variant, use the following versions to override the version of the Universal APK.
     * Otherwise, the Play Store will complain that the APK variants have the same version.
     */
    private static final Map<String, Integer> ABI_VERSION = [
        (ARCH_ARM32)        : 1,
        (ARCH_ARM64)        : 2,
        (ARCH_X86)          : 3,
        (ARCH_X86_64)       : 4,
    ]

    /** When split is enabled, multiple APKs are generated per each ABI. */
    private static final List DEFAULT_PLATFORMS = [
        PLATFORM_ARM32,
        PLATFORM_ARM64,
        PLATFORM_X86_64,
    ]

    private final static String propLocalEngineRepo = "local-engine-repo"
    private final static String propProcessResourcesProvider = "processResourcesProvider"

    /**
     * The name prefix for flutter builds. This is used to identify gradle tasks
     * where we expect the flutter tool to provide any error output, and skip the
     * standard Gradle error output in the FlutterEventLogger. If you change this,
     * be sure to change any instances of this string in symbols in the code below
     * to match.
     */
    static final String FLUTTER_BUILD_PREFIX = "flutterBuild"

    private Project project
    private File flutterRoot
    private File flutterExecutable
    private String localEngine
    private String localEngineHost
    private String localEngineSrcPath
    private Properties localProperties
    private String engineVersion
    private String engineRealm
    private List<Map<String, Object>> pluginList
    private List<Map<String, Object>> pluginDependencies

    /**
     * Flutter Docs Website URLs for help messages.
     */
    private final String kWebsiteDeploymentAndroidBuildConfig = "https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration"

    @Override
    void apply(Project project) {
        this.project = project

        Project rootProject = project.rootProject
        if (isFlutterAppProject()) {
            rootProject.tasks.register("generateLockfiles") {
                rootProject.subprojects.each { subproject ->
                    String gradlew = (OperatingSystem.current().isWindows()) ?
                        "${rootProject.projectDir}/gradlew.bat" : "${rootProject.projectDir}/gradlew"
                    rootProject.exec {
                        workingDir(rootProject.projectDir)
                        executable(gradlew)
                        args(":${subproject.name}:dependencies", "--write-locks")
                    }
                }
            }
        }

        String flutterRootPath = resolveProperty("flutter.sdk", System.env.FLUTTER_ROOT)
        if (flutterRootPath == null) {
            throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file or with a FLUTTER_ROOT environment variable.")
        }
        flutterRoot = project.file(flutterRootPath)
        if (!flutterRoot.isDirectory()) {
            throw new GradleException("flutter.sdk must point to the Flutter SDK directory")
        }

        engineVersion = useLocalEngine()
            ? "+" // Match any version since there's only one.
            : "1.0.0-" + Paths.get(flutterRoot.absolutePath, "bin", "internal", "engine.version").toFile().text.trim()

        engineRealm = Paths.get(flutterRoot.absolutePath, "bin", "internal", "engine.realm").toFile().text.trim()
        if (engineRealm) {
            engineRealm = engineRealm + "/"
        }

        // Configure the Maven repository.
        String hostedRepository = System.env.FLUTTER_STORAGE_BASE_URL ?: DEFAULT_MAVEN_HOST
        String repository = useLocalEngine()
            ? project.property(propLocalEngineRepo)
            : "$hostedRepository/${engineRealm}download.flutter.io"
        rootProject.allprojects {
            repositories {
                maven {
                    url(repository)
                }
            }
        }

        // Load shared gradle functions
        project.apply from: Paths.get(flutterRoot.absolutePath, "packages", "flutter_tools", "gradle", "src", "main", "groovy", "native_plugin_loader.groovy")

        FlutterExtension extension = project.extensions.create("flutter", FlutterExtension)
        Properties localProperties = new Properties()
        File localPropertiesFile = rootProject.file("local.properties")
        if (localPropertiesFile.exists()) {
            localPropertiesFile.withReader("UTF-8") { reader ->
                localProperties.load(reader)
            }
        }

        Object flutterVersionCode = localProperties.getProperty("flutter.versionCode")
        if (flutterVersionCode == null) {
            flutterVersionCode = "1"
        }
        extension.flutterVersionCode = flutterVersionCode

        Object flutterVersionName = localProperties.getProperty("flutter.versionName")
        if (flutterVersionName == null) {
            flutterVersionName = "1.0"
        }
        extension.flutterVersionName = flutterVersionName

        this.addFlutterTasks(project)

        // By default, assembling APKs generates fat APKs if multiple platforms are passed.
        // Configuring split per ABI allows to generate separate APKs for each abi.
        // This is a noop when building a bundle.
        if (shouldSplitPerAbi()) {
            project.android {
                splits {
                    abi {
                        // Enables building multiple APKs per ABI.
                        enable(true)
                        // Resets the list of ABIs that Gradle should create APKs for to none.
                        reset()
                        // Specifies that we do not want to also generate a universal APK that includes all ABIs.
                        universalApk(false)
                    }
                }
            }
        }
        final String propDeferredComponentNames = "deferred-component-names"
        if (project.hasProperty(propDeferredComponentNames)) {
            String[] componentNames = project.property(propDeferredComponentNames).split(",").collect {":${it}"}
            project.android {
                dynamicFeatures = componentNames
            }
        }

        getTargetPlatforms().each { targetArch ->
            String abiValue = PLATFORM_ARCH_MAP[targetArch]
            project.android {
                if (shouldSplitPerAbi()) {
                    splits {
                        abi {
                            include(abiValue)
                        }
                    }
                }
            }
        }

        String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter"
        flutterExecutable = Paths.get(flutterRoot.absolutePath, "bin", flutterExecutableName).toFile()

        // Validate that the provided Gradle, Java, AGP, and KGP versions are all within our
        // supported range.
        // TODO(gmackall) Dependency version checking is currently implemented as an additional
        // Gradle plugin because we can't import it from Groovy code. As part of the Groovy
        // -> Kotlin migration, we should remove this complexity and perform the checks inside
        // of the main Flutter Gradle Plugin.
        // See https://github.com/flutter/flutter/issues/121541#issuecomment-1920363687.
        final Boolean shouldSkipDependencyChecks = project.hasProperty("skipDependencyChecks") && project.getProperty("skipDependencyChecks");
        if (!shouldSkipDependencyChecks) {
            try {
                final String dependencyCheckerPluginPath = Paths.get(flutterRoot.absolutePath,
                        "packages", "flutter_tools", "gradle", "src", "main", "kotlin",
                        "dependency_version_checker.gradle.kts")
                project.apply from: dependencyCheckerPluginPath
            } catch (Exception ignored) {
                project.logger.error("Warning: Flutter was unable to detect project Gradle, Java, " +
                        "AGP, and KGP versions. Skipping dependency version checking. Error was: "
                        + ignored)
            }
        }

        // Use Kotlin DSL to handle baseApplicationName logic due to Groovy dynamic dispatch bug.
        project.apply from: Paths.get(flutterRoot.absolutePath, "packages", "flutter_tools", "gradle", "src", "main", "kotlin", "flutter.gradle.kts")

        String flutterProguardRules = Paths.get(flutterRoot.absolutePath, "packages", "flutter_tools",
                "gradle", "flutter_proguard_rules.pro")
        project.android.buildTypes {
            // Add profile build type.
            profile {
                initWith(debug)
                if (it.hasProperty("matchingFallbacks")) {
                    matchingFallbacks = ["debug", "release"]
                }
            }
            // TODO(garyq): Shrinking is only false for multi apk split aot builds, where shrinking is not allowed yet.
            // This limitation has been removed experimentally in gradle plugin version 4.2, so we can remove
            // this check when we upgrade to 4.2+ gradle. Currently, deferred components apps may see
            // increased app size due to this.
            if (shouldShrinkResources(project)) {
                release {
                    // Enables code shrinking, obfuscation, and optimization for only
                    // your project's release build type.
                    minifyEnabled(true)
                    // Enables resource shrinking, which is performed by the Android Gradle plugin.
                    // The resource shrinker can't be used for libraries.
                    shrinkResources(isBuiltAsApp(project))
                    // Fallback to `android/app/proguard-rules.pro`.
                    // This way, custom Proguard rules can be configured as needed.
                    proguardFiles(project.android.getDefaultProguardFile("proguard-android.txt"), flutterProguardRules, "proguard-rules.pro")
                }
            }
        }

        if (useLocalEngine()) {
            // This is required to pass the local engine to flutter build aot.
            String engineOutPath = project.property("local-engine-out")
            File engineOut = project.file(engineOutPath)
            if (!engineOut.isDirectory()) {
                throw new GradleException("local-engine-out must point to a local engine build")
            }
            localEngine = engineOut.name
            localEngineSrcPath = engineOut.parentFile.parent

            String engineHostOutPath = project.property("local-engine-host-out")
            File engineHostOut = project.file(engineHostOutPath)
            if (!engineHostOut.isDirectory()) {
                throw new GradleException("local-engine-host-out must point to a local engine host build")
            }
            localEngineHost = engineHostOut.name
        }
        project.android.buildTypes.all(this.&addFlutterDependencies)
    }

    private static Boolean shouldShrinkResources(Project project) {
        final String propShrink = "shrink"
        if (project.hasProperty(propShrink)) {
            return project.property(propShrink).toBoolean()
        }
        return true
    }

    private static String toCamelCase(List<String> parts) {
        if (parts.empty) {
            return ""
        }
        return "${parts[0]}${parts[1..-1].collect { it.capitalize() }.join('')}"
    }

    private static Properties readPropertiesIfExist(File propertiesFile) {
        Properties result = new Properties()
        if (propertiesFile.exists()) {
            propertiesFile.withReader("UTF-8") { reader -> result.load(reader) }
        }
        return result
    }

    private static Boolean isBuiltAsApp(Project project) {
        // Projects are built as applications when the they use the `com.android.application`
        // plugin.
        return project.plugins.hasPlugin("com.android.application")
    }

    private static void addApiDependencies(Project project, String variantName, Object dependency, Closure config = null) {
        String configuration
        // `compile` dependencies are now `api` dependencies.
        if (project.getConfigurations().findByName("api")) {
            configuration = "${variantName}Api"
        } else {
            configuration = "${variantName}Compile"
        }
        project.dependencies.add(configuration, dependency, config)
    }

    // Add a task that can be called on flutter projects that prints the Java version used in Gradle.
    //
    // Format of the output of this task can be used in debugging what version of Java Gradle is using.
    // Not recommended for use in time sensitive commands like `flutter run` or `flutter build` as
    // Gradle is slower than we want. Particularly in light of https://github.com/flutter/flutter/issues/119196.
    private static void addTaskForJavaVersion(Project project) {
        // Warning: the name of this task is used by other code. Change with caution.
        project.tasks.register("javaVersion") {
            description "Print the current java version used by gradle. "
                "see: https://docs.gradle.org/current/javadoc/org/gradle/api/JavaVersion.html"
            doLast {
                println(JavaVersion.current())
            }
        }
    }

    // Add a task that can be called on Flutter projects that prints the available build variants
    // in Gradle.
    //
    // This task prints variants in this format:
    //
    // BuildVariant: debug
    // BuildVariant: release
    // BuildVariant: profile
    //
    // Format of the output of this task is used by `AndroidProject.getBuildVariants`.
    private static void addTaskForPrintBuildVariants(Project project) {
        // Warning: The name of this task is used by `AndroidProject.getBuildVariants`.
        project.tasks.register("printBuildVariants") {
            description "Prints out all build variants for this Android project"
            doLast {
                project.android.applicationVariants.all { variant ->
                    println "BuildVariant: ${variant.name}"
                }
            }
        }
    }

    // Add a task that can be called on Flutter projects that outputs app link related project
    // settings into a json file.
    //
    // See https://developer.android.com/training/app-links/ for more information about app link.
    //
    // The json will be saved in path stored in outputPath parameter.
    //
    // An example json:
    // {
    //   applicationId: "com.example.app",
    //   deeplinks: [
    //     {"scheme":"http", "host":"example.com", "path":".*"},
    //     {"scheme":"https","host":"example.com","path":".*"}
    //   ]
    // }
    //
    // The output file is parsed and used by devtool.
    private static void addTasksForOutputsAppLinkSettings(Project project) {
        project.android.applicationVariants.all { variant ->
            // Warning: The name of this task is used by AndroidBuilder.outputsAppLinkSettings
            project.tasks.register("output${variant.name.capitalize()}AppLinkSettings") {
                description "stores app links settings for the given build variant of this Android project into a json file."
                variant.outputs.all { output ->
                    // Deeplinks are defined in AndroidManifest.xml and is only available after
                    // `processResourcesProvider`.
                    Object processResources = output.hasProperty(propProcessResourcesProvider) ?
                            output.processResourcesProvider.get() : output.processResources
                    dependsOn processResources.name
                }
                doLast {
                    AppLinkSettings appLinkSettings = new AppLinkSettings()
                    appLinkSettings.applicationId = variant.applicationId
                    appLinkSettings.deeplinks = [] as Set<Deeplink>
                    variant.outputs.all { output ->
                        Object processResources = output.hasProperty(propProcessResourcesProvider) ?
                                output.processResourcesProvider.get() : output.processResources
                        def manifest = new XmlParser().parse(processResources.manifestFile)
                        manifest.application.activity.each { activity ->
                            activity."meta-data".each { metadata ->
                                boolean nameAttribute = metadata.attributes().find { it.key == 'android:name' }?.value == 'flutter_deeplinking_enabled'
                                boolean valueAttribute = metadata.attributes().find { it.key == 'android:value' }?.value == 'true'
                                if (nameAttribute && valueAttribute) {
                                    appLinkSettings.deeplinkingFlagEnabled = true
                                }
                            }
                            activity."intent-filter".each { appLinkIntent ->
                                // Print out the host attributes in data tags.
                                Set<String> schemes = [] as Set<String>
                                Set<String> hosts = [] as Set<String>
                                Set<String> paths = [] as Set<String>
                                IntentFilterCheck intentFilterCheck = new IntentFilterCheck()

                                if (appLinkIntent.attributes().find { it.key == 'android:autoVerify' }?.value == 'true') {
                                    intentFilterCheck.hasAutoVerify = true
                            }
                                appLinkIntent.'action'.each { action ->
                                    if (action.attributes().find { it.key == 'android:name' }?.value == 'android.intent.action.VIEW') {
                                        intentFilterCheck.hasActionView = true
                                }
                        }
                                appLinkIntent.'category'.each { category ->
                                    if (category.attributes().find { it.key == 'android:name' }?.value == 'android.intent.category.DEFAULT') {
                                        intentFilterCheck.hasDefaultCategory = true
                                }
                                    if (category.attributes().find { it.key == 'android:name' }?.value == 'android.intent.category.BROWSABLE') {
                                        intentFilterCheck.hasBrowsableCategory = true
                    }
                }
                                appLinkIntent.data.each { data ->
                                    data.attributes().each { entry ->
                                        if (entry.key instanceof QName) {
                                            switch (entry.key.getLocalPart()) {
                                                case "scheme":
                                                    schemes.add(entry.value)
                                                    break
                                                case "host":
                                                    hosts.add(entry.value)
                                                    break
                                                case "pathAdvancedPattern":
                                                case "pathPattern":
                                                case "path":
                                                    paths.add(entry.value)
                                                    break
                                                case "pathPrefix":
                                                    paths.add("${entry.value}.*")
                                                    break
                                                case "pathSuffix":
                                                    paths.add(".*${entry.value}")
                                                    break
                                            }
                                        }
                                    }
                                }
                                if(!hosts.isEmpty() || !paths.isEmpty()){
                                    if(schemes.isEmpty()){schemes.add(null)}
                                    if(hosts.isEmpty()){hosts.add(null)}
                                    if(paths.isEmpty()){paths.add('.*')}
                                    schemes.each { scheme ->
                                        hosts.each { host ->
                                            paths.each { path ->
                                                appLinkSettings.deeplinks.add(new Deeplink(scheme: scheme, host: host, path: path, intentFilterCheck: intentFilterCheck))
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    JsonGenerator generator = new JsonGenerator.Options().build()
                    new File(project.getProperty("outputPath")).write(generator.toJson(appLinkSettings))
                }
            }
        }
    }

    /**
     * Returns a Flutter build mode suitable for the specified Android buildType.
     *
     * The BuildType DSL type is not public, and is therefore omitted from the signature.
     *
     * @return "debug", "profile", or "release" (fall-back).
     */
    private static String buildModeFor(buildType) {
        if (buildType.name == "profile") {
            return "profile"
        } else if (buildType.debuggable) {
            return "debug"
        }
        return "release"
    }

    /**
     * Adds the dependencies required by the Flutter project.
     * This includes:
     *    1. The embedding
     *    2. libflutter.so
     */
    void addFlutterDependencies(buildType) {
        String flutterBuildMode = buildModeFor(buildType)
        if (!supportsBuildMode(flutterBuildMode)) {
            return
        }
        // The embedding is set as an API dependency in a Flutter plugin.
        // Therefore, don't make the app project depend on the embedding if there are Flutter
        // plugins.
        // This prevents duplicated classes when using custom build types. That is, a custom build
        // type like profile is used, and the plugin and app projects have API dependencies on the
        // embedding.
        if (!isFlutterAppProject() || getPluginList(project).size() == 0) {
            addApiDependencies(project, buildType.name,
                    "io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion")
        }
        List<String> platforms = getTargetPlatforms().collect()
        // Debug mode includes x86 and x64, which are commonly used in emulators.
        if (flutterBuildMode == "debug" && !useLocalEngine()) {
            platforms.add("android-x86")
            platforms.add("android-x64")
        }
        platforms.each { platform ->
            String arch = PLATFORM_ARCH_MAP[platform].replace("-", "_")
            // Add the `libflutter.so` dependency.
            addApiDependencies(project, buildType.name,
                    "io.flutter:${arch}_$flutterBuildMode:$engineVersion")
        }
    }

    /**
     * Configures the Flutter plugin dependencies.
     *
     * The plugins are added to pubspec.yaml. Then, upon running `flutter pub get`,
     * the tool generates a `.flutter-plugins-dependencies` file, which contains a map to each plugin location.
     * Finally, the project's `settings.gradle` loads each plugin's android directory as a subproject.
     */
    private void configurePlugins(Project project) {
        configureLegacyPluginEachProjects(project)
        getPluginList(project).each(this.&configurePluginProject)
        getPluginList(project).each(this.&configurePluginDependencies)
    }

    // TODO(54566, 48918): Can remove once the issues are resolved.
    //  This means all references to `.flutter-plugins` are then removed and
    //  apps only depend exclusively on the `plugins` property in `.flutter-plugins-dependencies`.
    /**
     * Workaround to load non-native plugins for developers who may still use an
     * old `settings.gradle` which includes all the plugins from the
     * `.flutter-plugins` file, even if not made for Android.
     * The settings.gradle then:
     *     1) tries to add the android plugin implementation, which does not
     *        exist at all, but is also not included successfully
     *        (which does not throw an error and therefore isn't a problem), or
     *     2) includes the plugin successfully as a valid android plugin
     *        directory exists, even if the surrounding flutter package does not
     *        support the android platform (see e.g. apple_maps_flutter: 1.0.1).
     *        So as it's included successfully it expects to be added as API.
     *        This is only possible by taking all plugins into account, which
     *        only appear on the `dependencyGraph` and in the `.flutter-plugins` file.
     * So in summary the plugins are currently selected from the `dependencyGraph`
     * and filtered then with the [doesSupportAndroidPlatform] method instead of
     * just using the `plugins.android` list.
     */
    private void configureLegacyPluginEachProjects(Project project) {
        try {
            if (!settingsGradleFile(project).text.contains("'.flutter-plugins'")) {
                return
            }
        } catch (FileNotFoundException ignored) {
            throw new GradleException("settings.gradle/settings.gradle.kts does not exist: ${settingsGradleFile(project).absolutePath}")
        }
        List<Map<String, Object>> deps = getPluginDependencies(project)
        List<String> plugins = getPluginList(project).collect { it.name as String }
        deps.removeIf { plugins.contains(it.name) }
        deps.each {
            Project pluginProject = project.rootProject.findProject(":${it.name}")
            if (pluginProject == null) {
                // Plugin was not included in `settings.gradle`, but is listed in `.flutter-plugins`.
                project.logger.error("Plugin project :${it.name} listed, but not found. Please fix your settings.gradle/settings.gradle.kts.")
            } else if (pluginSupportsAndroidPlatform(pluginProject)) {
                // Plugin has a functioning `android` folder and is included successfully, although it's not supported.
                // It must be configured nonetheless, to not throw an "Unresolved reference" exception.
                configurePluginProject(it)
            /* groovylint-disable-next-line EmptyElseBlock */
            } else {
            // Plugin has no or an empty `android` folder. No action required.
            }
        }
    }

    // TODO(54566): Can remove this function and its call sites once resolved.
    /**
     * Returns `true` if the given project is a plugin project having an `android` directory
     * containing a `build.gradle` or `build.gradle.kts` file.
     */
    private Boolean pluginSupportsAndroidPlatform(Project project) {
        File buildGradle = new File(project.projectDir.parentFile, "android" + File.separator + "build.gradle")
        File buildGradleKts = new File(project.projectDir.parentFile, "android" + File.separator + "build.gradle.kts")
        return buildGradle.exists() || buildGradleKts.exists()
    }

    /**
     * Returns the Gradle build script for the build. When both Groovy and
     * Kotlin variants exist, then Groovy (build.gradle) is preferred over
     * Kotlin (build.gradle.kts). This is the same behavior as Gradle 8.5.
     */
    private File buildGradleFile(Project project) {
        File buildGradle = new File(project.projectDir.parentFile, "app" + File.separator + "build.gradle")
        File buildGradleKts = new File(project.projectDir.parentFile, "app" + File.separator + "build.gradle.kts")
        if (buildGradle.exists() && buildGradleKts.exists()) {
            project.logger.error(
                "Both build.gradle and build.gradle.kts exist, so " +
                "build.gradle.kts is ignored. This is likely a mistake."
            )
        }

        return buildGradle.exists() ? buildGradle : buildGradleKts
    }

    /**
     * Returns the Gradle settings script for the build. When both Groovy and
     * Kotlin variants exist, then Groovy (settings.gradle) is preferred over
     * Kotlin (settings.gradle.kts). This is the same behavior as Gradle 8.5.
     */
    private File settingsGradleFile(Project project) {
        File settingsGradle = new File(project.projectDir.parentFile, "settings.gradle")
        File settingsGradleKts = new File(project.projectDir.parentFile, "settings.gradle.kts")
        if (settingsGradle.exists() && settingsGradleKts.exists()) {
            project.logger.error(
                "Both settings.gradle and settings.gradle.kts exist, so " +
                "settings.gradle.kts is ignored. This is likely a mistake."
            )
        }

        return settingsGradle.exists() ? settingsGradle : settingsGradleKts
    }

    /** Adds the plugin project dependency to the app project. */
    private void configurePluginProject(Map<String, Object> pluginObject) {
        assert(pluginObject.name instanceof String)
        Project pluginProject = project.rootProject.findProject(":${pluginObject.name}")
        if (pluginProject == null) {
            return
        }
        // Add plugin dependency to the app project.
        project.dependencies {
            api(pluginProject)
        }
        Closure addEmbeddingDependencyToPlugin = { buildType ->
            String flutterBuildMode = buildModeFor(buildType)
            // In AGP 3.5, the embedding must be added as an API implementation,
            // so java8 features are desugared against the runtime classpath.
            // For more, see https://github.com/flutter/flutter/issues/40126
            if (!supportsBuildMode(flutterBuildMode)) {
                return
            }
            if (!pluginProject.hasProperty("android")) {
                return
            }
            // Copy build types from the app to the plugin.
            // This allows to build apps with plugins and custom build types or flavors.
            pluginProject.android.buildTypes {
                "${buildType.name}" {}
            }
            // The embedding is API dependency of the plugin, so the AGP is able to desugar
            // default method implementations when the interface is implemented by a plugin.
            //
            // See https://issuetracker.google.com/139821726, and
            // https://github.com/flutter/flutter/issues/72185 for more details.
            addApiDependencies(
              pluginProject,
              buildType.name,
              "io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion"
            )
        }

        // Wait until the Android plugin loaded.
        pluginProject.afterEvaluate {
            // Checks if there is a mismatch between the plugin compileSdkVersion and the project compileSdkVersion.
            if (pluginProject.android.compileSdkVersion > project.android.compileSdkVersion) {
                project.logger.quiet("Warning: The plugin ${pluginObject.name} requires Android SDK version ${getCompileSdkFromProject(pluginProject)} or higher.")
                project.logger.quiet("For more information about build configuration, see $kWebsiteDeploymentAndroidBuildConfig.")
            }

            project.android.buildTypes.all(addEmbeddingDependencyToPlugin)
        }
    }

    /**
     * Compares semantic versions ignoring labels.
     *
     * If the versions are equal (ignoring labels), returns one of the two strings arbitrarily.
     *
     * If minor or patch are omitted (non-conformant to semantic versioning), they are considered zero.
     * If the provided versions in both are equal, the longest version string is returned.
     * For example, "2.8.0" vs "2.8" will always consider "2.8.0" to be the most recent version.
     * TODO: Remove this or compareVersionStrings. This does not handle strings like "8.6-rc-2".
     */
    static String mostRecentSemanticVersion(String version1, String version2) {
        List version1Tokenized = version1.tokenize(".")
        List version2Tokenized = version2.tokenize(".")
        int version1numTokens = version1Tokenized.size()
        int version2numTokens = version2Tokenized.size()
        int minNumTokens = Math.min(version1numTokens, version2numTokens)
        for (int i = 0; i < minNumTokens; i++) {
            int num1 = version1Tokenized[i].toInteger()
            int num2 = version2Tokenized[i].toInteger()
            if (num1 > num2) {
                return version1
            }
            if (num2 > num1) {
                return version2
            }
        }
        if (version1numTokens > version2numTokens) {
            return version1
        }
        return version2
    }

    /** Prints error message and fix for any plugin compileSdkVersion or ndkVersion that are higher than the project. */
    private void detectLowCompileSdkVersionOrNdkVersion() {
        project.afterEvaluate {
            // Default to int max if using a preview version to skip the sdk check.
            int projectCompileSdkVersion = Integer.MAX_VALUE
            // Stable versions use ints, legacy preview uses string.
            if (getCompileSdkFromProject(project).isInteger()) {
                projectCompileSdkVersion = getCompileSdkFromProject(project) as int
            }
            int maxPluginCompileSdkVersion = projectCompileSdkVersion
            String ndkVersionIfUnspecified = "21.1.6352462" /* The default for AGP 4.1.0 used in old templates. */
            String projectNdkVersion = project.android.ndkVersion ?: ndkVersionIfUnspecified
            String maxPluginNdkVersion = projectNdkVersion
            int numProcessedPlugins = getPluginList(project).size()
            List<Tuple2<String, String>> pluginsWithHigherSdkVersion = []
            List<Tuple2<String, String>> pluginsWithDifferentNdkVersion = []

            getPluginList(project).each { pluginObject ->
                assert(pluginObject.name instanceof String)
                Project pluginProject = project.rootProject.findProject(":${pluginObject.name}")
                if (pluginProject == null) {
                    return
                }
                pluginProject.afterEvaluate {
                    // Default to int min if using a preview version to skip the sdk check.
                    int pluginCompileSdkVersion = Integer.MIN_VALUE
                    // Stable versions use ints, legacy preview uses string.
                    if (getCompileSdkFromProject(pluginProject).isInteger()) {
                        pluginCompileSdkVersion = getCompileSdkFromProject(pluginProject) as int
                    }

                    maxPluginCompileSdkVersion = Math.max(pluginCompileSdkVersion, maxPluginCompileSdkVersion)
                    if (pluginCompileSdkVersion > projectCompileSdkVersion) {
                        pluginsWithHigherSdkVersion.add(new Tuple(pluginProject.name, pluginCompileSdkVersion))
                    }

                    String pluginNdkVersion = pluginProject.android.ndkVersion ?: ndkVersionIfUnspecified
                    maxPluginNdkVersion = mostRecentSemanticVersion(pluginNdkVersion, maxPluginNdkVersion)
                    if (pluginNdkVersion != projectNdkVersion) {
                        pluginsWithDifferentNdkVersion.add(new Tuple(pluginProject.name, pluginNdkVersion))
                    }

                    numProcessedPlugins--
                    if (numProcessedPlugins == 0) {
                        if (maxPluginCompileSdkVersion > projectCompileSdkVersion) {
                            project.logger.error("Your project is configured to compile against Android SDK $projectCompileSdkVersion, but the following plugin(s) require to be compiled against a higher Android SDK version:")
                            for (Tuple2<String, String> pluginToCompileSdkVersion : pluginsWithHigherSdkVersion) {
                                project.logger.error("- ${pluginToCompileSdkVersion.first} compiles against Android SDK ${pluginToCompileSdkVersion.second}")
                            }
                            project.logger.error("""\
                                Fix this issue by compiling against the highest Android SDK version (they are backward compatible).
                                Add the following to ${buildGradleFile(project).path}:

                                    android {
                                        compileSdk = ${maxPluginCompileSdkVersion}
                                        ...
                                    }
                                """.stripIndent())
                        }
                        if (maxPluginNdkVersion != projectNdkVersion) {
                            project.logger.error("Your project is configured with Android NDK $projectNdkVersion, but the following plugin(s) depend on a different Android NDK version:")
                            for (Tuple2<String, String> pluginToNdkVersion : pluginsWithDifferentNdkVersion) {
                                project.logger.error("- ${pluginToNdkVersion.first} requires Android NDK ${pluginToNdkVersion.second}")
                            }
                            project.logger.error("""\
                                Fix this issue by using the highest Android NDK version (they are backward compatible).
                                Add the following to ${buildGradleFile(project).path}:

                                    android {
                                        ndkVersion = \"${maxPluginNdkVersion}\"
                                        ...
                                    }
                                """.stripIndent())
                        }
                    }
                }
            }
        }
    }

    /**
     * Returns the portion of the compileSdkVersion string that corresponds to either the numeric
     * or string version.
     */
    private String getCompileSdkFromProject(Project gradleProject) {
        return gradleProject.android.compileSdkVersion.substring(8)
    }

    /**
     * Add the dependencies on other plugin projects to the plugin project.
     * A plugin A can depend on plugin B. As a result, this dependency must be surfaced by
     * making the Gradle plugin project A depend on the Gradle plugin project B.
     */
    private void configurePluginDependencies(Map<String, Object> pluginObject) {
        assert(pluginObject.name instanceof String)
        Project pluginProject = project.rootProject.findProject(":${pluginObject.name}")
        if (pluginProject == null) {
            return
        }
        def dependencies = pluginObject.dependencies
        assert(dependencies instanceof List<String>)
        dependencies.each { pluginDependencyName ->
            if (pluginDependencyName.empty) {
                return
            }
            Project dependencyProject = project.rootProject.findProject(":$pluginDependencyName")
            if (dependencyProject == null) {
                return
            }
            // Wait for the Android plugin to load and add the dependency to the plugin project.
            pluginProject.afterEvaluate {
                pluginProject.dependencies {
                    implementation(dependencyProject)
                }
            }
        }
    }

    /**
     * Gets the list of plugins (as map) that support the Android platform.
     *
     * The map value contains either the plugins `name` (String),
     * its `path` (String), or its `dependencies` (List<String>).
     * See [NativePluginLoader#getPlugins] in packages/flutter_tools/gradle/src/main/groovy/native_plugin_loader.groovy
     */
    private List<Map<String, Object>> getPluginList(Project project) {
        if (pluginList == null) {
            pluginList = project.ext.nativePluginLoader.getPlugins(getFlutterSourceDirectory())
        }
        return pluginList
    }

    // TODO(54566, 48918): Remove in favor of [getPluginList] only, see also
    //  https://github.com/flutter/flutter/blob/1c90ed8b64d9ed8ce2431afad8bc6e6d9acc4556/packages/flutter_tools/lib/src/flutter_plugins.dart#L212
    /** Gets the plugins dependencies from `.flutter-plugins-dependencies`. */
    private List<Map<String, Object>> getPluginDependencies(Project project) {
        if (pluginDependencies == null) {
            Map meta = project.ext.nativePluginLoader.getDependenciesMetadata(getFlutterSourceDirectory())
            if (meta == null) {
                pluginDependencies = []
            } else {
                assert(meta.dependencyGraph instanceof List<Map>)
                pluginDependencies = meta.dependencyGraph as List<Map<String, Object>>
            }
        }
        return pluginDependencies
    }

    private String resolveProperty(String name, String defaultValue) {
        if (localProperties == null) {
            localProperties = readPropertiesIfExist(new File(project.projectDir.parentFile, "local.properties"))
        }
        String result
        if (project.hasProperty(name)) {
            result = project.property(name)
        }
        if (result == null) {
            result = localProperties.getProperty(name)
        }
        if (result == null) {
            result = defaultValue
        }
        return result
    }

    private List<String> getTargetPlatforms() {
        final String propTargetPlatform = "target-platform"
        if (!project.hasProperty(propTargetPlatform)) {
            return DEFAULT_PLATFORMS
        }
        return project.property(propTargetPlatform).split(",").collect {
            if (!PLATFORM_ARCH_MAP[it]) {
                throw new GradleException("Invalid platform: $it.")
            }
            return it
        }
    }

    private Boolean shouldSplitPerAbi() {
        return project.findProperty("split-per-abi")?.toBoolean() ?: false
    }

    private Boolean useLocalEngine() {
        return project.hasProperty(propLocalEngineRepo)
    }

    private Boolean isVerbose() {
        return project.findProperty("verbose")?.toBoolean() ?: false
    }

    /** Whether to build the debug app in "fast-start" mode. */
    private Boolean isFastStart() {
        return project.findProperty("fast-start")?.toBoolean() ?: false
    }

    /**
     * Returns true if the build mode is supported by the current call to Gradle.
     * This only relevant when using a local engine. Because the engine
     * is built for a specific mode, the call to Gradle must match that mode.
     */
    private Boolean supportsBuildMode(String flutterBuildMode) {
        if (!useLocalEngine()) {
            return true
        }
        final String propLocalEngineBuildMode = "local-engine-build-mode"
        assert(project.hasProperty(propLocalEngineBuildMode))
        // Don't configure dependencies for a build mode that the local engine
        // doesn't support.
        return project.property(propLocalEngineBuildMode) == flutterBuildMode
    }

    /**
     * Gets the directory that contains the Flutter source code.
     * This is the directory containing the `android/` directory.
     */
    private File getFlutterSourceDirectory() {
        if (project.flutter.source == null) {
            throw new GradleException("Must provide Flutter source directory")
        }
        return project.file(project.flutter.source)
    }

    /**
     * Gets the target file. This is typically `lib/main.dart`.
     */
    private String getFlutterTarget() {
        String target = project.flutter.target
        if (target == null) {
            target = "lib/main.dart"
        }
        final String propTarget = "target"
        if (project.hasProperty(propTarget)) {
            target = project.property(propTarget)
        }
        return target
    }

    // TODO: Remove this AGP hack. https://github.com/flutter/flutter/issues/109560
    /**
     * In AGP 4.0, the Android linter task depends on the JAR tasks that generate `libapp.so`.
     * When building APKs, this causes an issue where building release requires the debug JAR,
     * but Gradle won't build debug.
     *
     * To workaround this issue, only configure the JAR task that is required given the task
     * from the command line.
     *
     * The AGP team said that this issue is fixed in Gradle 7.0, which isn't released at the
     * time of adding this code. Once released, this can be removed. However, after updating to
     * AGP/Gradle 7.2.0/7.5, removing this hack still causes build failures. Further
     * investigation necessary to remove this.
     *
     * Tested cases:
     * * `./gradlew assembleRelease`
     * * `./gradlew app:assembleRelease.`
     * * `./gradlew assemble{flavorName}Release`
     * * `./gradlew app:assemble{flavorName}Release`
     * * `./gradlew assemble.`
     * * `./gradlew app:assemble.`
     * * `./gradlew bundle.`
     * * `./gradlew bundleRelease.`
     * * `./gradlew app:bundleRelease.`
     *
     * Related issues:
     * https://issuetracker.google.com/issues/158060799
     * https://issuetracker.google.com/issues/158753935
     */
    private boolean shouldConfigureFlutterTask(Task assembleTask) {
        List<String> cliTasksNames = project.gradle.startParameter.taskNames
        if (cliTasksNames.size() != 1 || !cliTasksNames.first().contains("assemble")) {
            return true
        }
        String taskName = cliTasksNames.first().split(":").last()
        if (taskName == "assemble") {
            return true
        }
        if (taskName == assembleTask.name) {
            return true
        }
        if (taskName.endsWith("Release") && assembleTask.name.endsWith("Release")) {
            return true
        }
        if (taskName.endsWith("Debug") && assembleTask.name.endsWith("Debug")) {
            return true
        }
        if (taskName.endsWith("Profile") && assembleTask.name.endsWith("Profile")) {
            return true
        }
        return false
    }

    private Task getAssembleTask(variant) {
        // `assemble` became `assembleProvider` in AGP 3.3.0.
        return variant.hasProperty("assembleProvider") ? variant.assembleProvider.get() : variant.assemble
    }

    private boolean isFlutterAppProject() {
        return project.android.hasProperty("applicationVariants")
    }

    private void addFlutterTasks(Project project) {
        if (project.state.failure) {
            return
        }
        String[] fileSystemRootsValue = null
        final String propFileSystemRoots = "filesystem-roots"
        if (project.hasProperty(propFileSystemRoots)) {
            fileSystemRootsValue = project.property(propFileSystemRoots).split("\\|")
        }
        String fileSystemSchemeValue = null
        final String propFileSystemScheme = "filesystem-scheme"
        if (project.hasProperty(propFileSystemScheme)) {
            fileSystemSchemeValue = project.property(propFileSystemScheme)
        }
        Boolean trackWidgetCreationValue = true
        final String propTrackWidgetCreation = "track-widget-creation"
        if (project.hasProperty(propTrackWidgetCreation)) {
            trackWidgetCreationValue = project.property(propTrackWidgetCreation).toBoolean()
        }
        String frontendServerStarterPathValue = null
        final String propFrontendServerStarterPath = "frontend-server-starter-path"
        if (project.hasProperty(propFrontendServerStarterPath)) {
            frontendServerStarterPathValue = project.property(propFrontendServerStarterPath)
        }
        String extraFrontEndOptionsValue = null
        final String propExtraFrontEndOptions = "extra-front-end-options"
        if (project.hasProperty(propExtraFrontEndOptions)) {
            extraFrontEndOptionsValue = project.property(propExtraFrontEndOptions)
        }
        String extraGenSnapshotOptionsValue = null
        final String propExtraGenSnapshotOptions = "extra-gen-snapshot-options"
        if (project.hasProperty(propExtraGenSnapshotOptions)) {
            extraGenSnapshotOptionsValue = project.property(propExtraGenSnapshotOptions)
        }
        String splitDebugInfoValue = null
        final String propSplitDebugInfo = "split-debug-info"
        if (project.hasProperty(propSplitDebugInfo)) {
            splitDebugInfoValue = project.property(propSplitDebugInfo)
        }
        Boolean dartObfuscationValue = false
        final String propDartObfuscation = "dart-obfuscation"
        if (project.hasProperty(propDartObfuscation)) {
            dartObfuscationValue = project.property(propDartObfuscation).toBoolean()
        }
        Boolean treeShakeIconsOptionsValue = false
        final String propTreeShakeIcons = "tree-shake-icons"
        if (project.hasProperty(propTreeShakeIcons)) {
            treeShakeIconsOptionsValue = project.property(propTreeShakeIcons).toBoolean()
        }
        String dartDefinesValue = null
        final String propDartDefines = "dart-defines"
        if (project.hasProperty(propDartDefines)) {
            dartDefinesValue = project.property(propDartDefines)
        }
        String bundleSkSLPathValue
        final String propBundleSkslPath = "bundle-sksl-path"
        if (project.hasProperty(propBundleSkslPath)) {
            bundleSkSLPathValue = project.property(propBundleSkslPath)
        }
        String performanceMeasurementFileValue
        final String propPerformanceMeasurementFile = "performance-measurement-file"
        if (project.hasProperty(propPerformanceMeasurementFile)) {
            performanceMeasurementFileValue = project.property(propPerformanceMeasurementFile)
        }
        String codeSizeDirectoryValue
        final String propCodeSizeDirectory = "code-size-directory"
        if (project.hasProperty(propCodeSizeDirectory)) {
            codeSizeDirectoryValue = project.property(propCodeSizeDirectory)
        }
        Boolean deferredComponentsValue = false
        final String propDeferredComponents = "deferred-components"
        if (project.hasProperty(propDeferredComponents)) {
            deferredComponentsValue = project.property(propDeferredComponents).toBoolean()
        }
        Boolean validateDeferredComponentsValue = true
        final String propValidateDeferredComponents = "validate-deferred-components"
        if (project.hasProperty(propValidateDeferredComponents)) {
            validateDeferredComponentsValue = project.property(propValidateDeferredComponents).toBoolean()
        }
        addTaskForJavaVersion(project)
        if (isFlutterAppProject()) {
            addTaskForPrintBuildVariants(project)
            addTasksForOutputsAppLinkSettings(project)
        }
        List<String> targetPlatforms = getTargetPlatforms()
        def addFlutterDeps = { variant ->
            if (shouldSplitPerAbi()) {
                variant.outputs.each { output ->
                    // Assigns the new version code to versionCodeOverride, which changes the version code
                    // for only the output APK, not for the variant itself. Skipping this step simply
                    // causes Gradle to use the value of variant.versionCode for the APK.
                    // For more, see https://developer.android.com/studio/build/configure-apk-splits
                    Integer abiVersionCode = ABI_VERSION.get(output.getFilter(OutputFile.ABI))
                    if (abiVersionCode != null) {
                        output.versionCodeOverride =
                            abiVersionCode * 1000 + variant.versionCode
                    }
                }
            }
            // Build an AAR when this property is defined.
            boolean isBuildingAar = project.hasProperty("is-plugin")
            // In add to app scenarios, a Gradle project contains a `:flutter` and `:app` project.
            // `:flutter` is used as a subproject when these tasks exists and the build isn't building an AAR.
            Task packageAssets = project.tasks.findByPath(":flutter:package${variant.name.capitalize()}Assets")
            Task cleanPackageAssets = project.tasks.findByPath(":flutter:cleanPackage${variant.name.capitalize()}Assets")
            boolean isUsedAsSubproject = packageAssets && cleanPackageAssets && !isBuildingAar

            String variantBuildMode = buildModeFor(variant.buildType)
            String flavorValue = variant.getFlavorName()
            String taskName = toCamelCase(["compile", FLUTTER_BUILD_PREFIX, variant.name])
            // Be careful when configuring task below, Groovy has bizarre
            // scoping rules: writing `verbose isVerbose()` means calling
            // `isVerbose` on the task itself - which would return `verbose`
            // original value. You either need to hoist the value
            // into a separate variable `verbose verboseValue` or prefix with
            // `this` (`verbose this.isVerbose()`).
            FlutterTask compileTask = project.tasks.create(name: taskName, type: FlutterTask) {
                flutterRoot(this.flutterRoot)
                flutterExecutable(this.flutterExecutable)
                buildMode(variantBuildMode)
                minSdkVersion(variant.mergedFlavor.minSdkVersion.apiLevel)
                localEngine(this.localEngine)
                localEngineHost(this.localEngineHost)
                localEngineSrcPath(this.localEngineSrcPath)
                targetPath(getFlutterTarget())
                verbose(this.isVerbose())
                fastStart(this.isFastStart())
                fileSystemRoots(fileSystemRootsValue)
                fileSystemScheme(fileSystemSchemeValue)
                trackWidgetCreation(trackWidgetCreationValue)
                targetPlatformValues = targetPlatforms
                sourceDir(getFlutterSourceDirectory())
                intermediateDir(project.file("${project.buildDir}/$INTERMEDIATES_DIR/flutter/${variant.name}/"))
                frontendServerStarterPath(frontendServerStarterPathValue)
                extraFrontEndOptions(extraFrontEndOptionsValue)
                extraGenSnapshotOptions(extraGenSnapshotOptionsValue)
                splitDebugInfo(splitDebugInfoValue)
                treeShakeIcons(treeShakeIconsOptionsValue)
                dartObfuscation(dartObfuscationValue)
                dartDefines(dartDefinesValue)
                bundleSkSLPath(bundleSkSLPathValue)
                performanceMeasurementFile(performanceMeasurementFileValue)
                codeSizeDirectory(codeSizeDirectoryValue)
                deferredComponents(deferredComponentsValue)
                validateDeferredComponents(validateDeferredComponentsValue)
                flavor(flavorValue)
            }
            File libJar = project.file("${project.buildDir}/$INTERMEDIATES_DIR/flutter/${variant.name}/libs.jar")
            Task packJniLibsTask = project.tasks.create(name: "packJniLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) {
                destinationDirectory = libJar.parentFile
                archiveFileName = libJar.name
                dependsOn compileTask
                targetPlatforms.each { targetPlatform ->
                    String abi = PLATFORM_ARCH_MAP[targetPlatform]
                    from("${compileTask.intermediateDir}/${abi}") {
                        include "*.so"
                        // Move `app.so` to `lib/<abi>/libapp.so`
                        rename { String filename ->
                            return "lib/${abi}/lib${filename}"
                        }
                    }
                    // Copy the native assets created by build.dart and placed in build/native_assets by flutter assemble.
                    // The `$project.buildDir` is '.android/Flutter/build/' instead of 'build/'.
                    String buildDir = "${getFlutterSourceDirectory()}/build"
                    String nativeAssetsDir = "${buildDir}/native_assets/android/jniLibs/lib"
                    from("${nativeAssetsDir}/${abi}") {
                        include "*.so"
                        rename { String filename ->
                            return "lib/${abi}/${filename}"
                        }
                    }
                }
            }
            addApiDependencies(project, variant.name, project.files {
                packJniLibsTask
            })
            Task copyFlutterAssetsTask = project.tasks.create(
                name: "copyFlutterAssets${variant.name.capitalize()}",
                type: Copy,
            ) {
                dependsOn(compileTask)
                with(compileTask.assets)
                String currentGradleVersion = project.getGradle().getGradleVersion()

                // See https://docs.gradle.org/current/javadoc/org/gradle/api/file/ConfigurableFilePermissions.html
                // See https://github.com/flutter/flutter/pull/50047
                if (compareVersionStrings(currentGradleVersion, "8.3") >= 0) {
                    filePermissions {
                        user {
                            read = true
                            write = true
                        }
                    }
                } else {
                    // See https://docs.gradle.org/8.2/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:fileMode
                    // See https://github.com/flutter/flutter/pull/50047
                    fileMode(0644)
                }
                if (isUsedAsSubproject) {
                    dependsOn(packageAssets)
                    dependsOn(cleanPackageAssets)
                    into(packageAssets.outputDir)
                    return
                }
                // `variant.mergeAssets` will be removed at the end of 2019.
                def mergeAssets = variant.hasProperty("mergeAssetsProvider") ?
                    variant.mergeAssetsProvider.get() : variant.mergeAssets
                dependsOn(mergeAssets)
                dependsOn("clean${mergeAssets.name.capitalize()}")
                mergeAssets.mustRunAfter("clean${mergeAssets.name.capitalize()}")
                into(mergeAssets.outputDir)
            }
            if (!isUsedAsSubproject) {
                def variantOutput = variant.outputs.first()
                def processResources = variantOutput.hasProperty(propProcessResourcesProvider) ?
                    variantOutput.processResourcesProvider.get() : variantOutput.processResources
                processResources.dependsOn(copyFlutterAssetsTask)
            }
            // The following tasks use the output of copyFlutterAssetsTask,
            // so it's necessary to declare it as an dependency since Gradle 8.
            // See https://docs.gradle.org/8.1/userguide/validation_problems.html#implicit_dependency.
            def compressAssetsTask = project.tasks.findByName("compress${variant.name.capitalize()}Assets")
            if (compressAssetsTask) {
                compressAssetsTask.dependsOn(copyFlutterAssetsTask)
            }

            def bundleAarTask = project.tasks.findByName("bundle${variant.name.capitalize()}Aar")
            if (bundleAarTask) {
                bundleAarTask.dependsOn(copyFlutterAssetsTask)
            }

            return copyFlutterAssetsTask
        } // end def addFlutterDeps

        if (isFlutterAppProject()) {
            project.android.applicationVariants.all { variant ->
                Task assembleTask = getAssembleTask(variant)
                if (!shouldConfigureFlutterTask(assembleTask)) {
                    return
                }
                Task copyFlutterAssetsTask = addFlutterDeps(variant)
                def variantOutput = variant.outputs.first()
                def processResources = variantOutput.hasProperty(propProcessResourcesProvider) ?
                    variantOutput.processResourcesProvider.get() : variantOutput.processResources
                processResources.dependsOn(copyFlutterAssetsTask)

                // Copy the output APKs into a known location, so `flutter run` or `flutter build apk`
                // can discover them. By default, this is `<app-dir>/build/app/outputs/flutter-apk/<filename>.apk`.
                //
                // The filename consists of `app<-abi>?<-flavor-name>?-<build-mode>.apk`.
                // Where:
                //   * `abi` can be `armeabi-v7a|arm64-v8a|x86|x86_64` only if the flag `split-per-abi` is set.
                //   * `flavor-name` is the flavor used to build the app in lower case if the assemble task is called.
                //   * `build-mode` can be `release|debug|profile`.
                variant.outputs.all { output ->
                    assembleTask.doLast {
                        // `packageApplication` became `packageApplicationProvider` in AGP 3.3.0.
                        def outputDirectory = variant.hasProperty("packageApplicationProvider")
                            ? variant.packageApplicationProvider.get().outputDirectory
                            : variant.packageApplication.outputDirectory
                        //  `outputDirectory` is a `DirectoryProperty` in AGP 4.1.
                        String outputDirectoryStr = outputDirectory.metaClass.respondsTo(outputDirectory, "get")
                            ? outputDirectory.get()
                            : outputDirectory
                        String filename = "app"
                        String abi = output.getFilter(OutputFile.ABI)
                        if (abi != null && !abi.isEmpty()) {
                            filename += "-${abi}"
                        }
                        if (variant.flavorName != null && !variant.flavorName.isEmpty()) {
                            filename += "-${variant.flavorName.toLowerCase()}"
                        }
                        filename += "-${buildModeFor(variant.buildType)}"
                        project.copy {
                            from new File("$outputDirectoryStr/${output.outputFileName}")
                            into new File("${project.buildDir}/outputs/flutter-apk")
                            rename {
                                return "${filename}.apk"
                            }
                        }
                    }
                }
                // Copy the native assets created by build.dart and placed here by flutter assemble.
                String nativeAssetsDir = "${project.buildDir}/../native_assets/android/jniLibs/lib/"
                project.android.sourceSets.main.jniLibs.srcDir(nativeAssetsDir)
            }
            configurePlugins(project)
            detectLowCompileSdkVersionOrNdkVersion()
            return
        }
        // Flutter host module project (Add-to-app).
        String hostAppProjectName = project.rootProject.hasProperty("flutter.hostAppProjectName") ? project.rootProject.property("flutter.hostAppProjectName") : "app"
        Project appProject = project.rootProject.findProject(":${hostAppProjectName}")
        assert(appProject != null) : "Project :${hostAppProjectName} doesn't exist. To customize the host app project name, set `flutter.hostAppProjectName=<project-name>` in gradle.properties."
        // Wait for the host app project configuration.
        appProject.afterEvaluate {
            assert(appProject.android != null)
            project.android.libraryVariants.all { libraryVariant ->
                Task copyFlutterAssetsTask
                appProject.android.applicationVariants.all { appProjectVariant ->
                    Task appAssembleTask = getAssembleTask(appProjectVariant)
                    if (!shouldConfigureFlutterTask(appAssembleTask)) {
                        return
                    }
                    // Find a compatible application variant in the host app.
                    //
                    // For example, consider a host app that defines the following variants:
                    // | ----------------- | ----------------------------- |
                    // |   Build Variant   |   Flutter Equivalent Variant  |
                    // | ----------------- | ----------------------------- |
                    // |   freeRelease     |   release                     |
                    // |   freeDebug       |   debug                       |
                    // |   freeDevelop     |   debug                       |
                    // |   profile         |   profile                     |
                    // | ----------------- | ----------------------------- |
                    //
                    // This mapping is based on the following rules:
                    // 1. If the host app build variant name is `profile` then the equivalent
                    //    Flutter variant is `profile`.
                    // 2. If the host app build variant is debuggable
                    //    (e.g. `buildType.debuggable = true`), then the equivalent Flutter
                    //    variant is `debug`.
                    // 3. Otherwise, the equivalent Flutter variant is `release`.
                    String variantBuildMode = buildModeFor(libraryVariant.buildType)
                    if (buildModeFor(appProjectVariant.buildType) != variantBuildMode) {
                        return
                    }
                    if (copyFlutterAssetsTask == null) {
                        copyFlutterAssetsTask = addFlutterDeps(libraryVariant)
                    }
                    Task mergeAssets = project
                        .tasks
                        .findByPath(":${hostAppProjectName}:merge${appProjectVariant.name.capitalize()}Assets")
                    assert(mergeAssets)
                    mergeAssets.dependsOn(copyFlutterAssetsTask)
                }
            }
        }
        configurePlugins(project)
        detectLowCompileSdkVersionOrNdkVersion()
    }

    // compareTo implementation of version strings in the format of ints and periods
    // Requires non null objects.
    // Will not crash on RC candidate strings but considers all RC candidates the same version.
    static int compareVersionStrings(String firstString, String secondString) {
        List firstVersion = firstString.tokenize(".")
        List secondVersion = secondString.tokenize(".")

        int commonIndices = Math.min(firstVersion.size(), secondVersion.size())

        for (int i = 0; i < commonIndices; i++) {
            String firstAtIndex = firstVersion[i]
            String secondAtIndex = secondVersion[i]
            int firstInt = 0
            int secondInt = 0
            try {
                if (firstAtIndex.contains("-")) {
                    // Strip any chars after "-". For example "8.6-rc-2"
                    firstAtIndex = firstAtIndex.substring(0, firstAtIndex.indexOf('-'))
                }
                firstInt = firstAtIndex.toInteger()
            } catch (NumberFormatException nfe) {
                println(nfe)
            }
            try {
                if (firstAtIndex.contains("-")) {
                    // Strip any chars after "-". For example "8.6-rc-2"
                    secondAtIndex = secondAtIndex.substring(0, secondAtIndex.indexOf('-'))
                }
                secondInt = secondAtIndex.toInteger()
            } catch (NumberFormatException nfe) {
                println(nfe)
            }

            if (firstInt != secondInt) {
                // <=> in groovy delegates to compareTo
                return firstInt <=> secondInt
            }
        }

        // If we got this far then all the common indices are identical, so whichever version is longer must be more recent
        return firstVersion.size() <=> secondVersion.size()
    }

}

class AppLinkSettings {

    String applicationId
    Set<Deeplink> deeplinks
    boolean deeplinkingFlagEnabled

}

class IntentFilterCheck {

    boolean hasAutoVerify
    boolean hasActionView
    boolean hasDefaultCategory
    boolean hasBrowsableCategory

}

class Deeplink {
    String scheme, host, path
    IntentFilterCheck intentFilterCheck
    boolean equals(o) {
        if (o == null) {
            throw new NullPointerException()
        }
        if (o.getClass() != getClass()) {
            return false
        }
        return scheme == o.scheme &&
                host == o.host &&
                path == o.path
    }
}

abstract class BaseFlutterTask extends DefaultTask {

    @Internal
    File flutterRoot

    @Internal
    File flutterExecutable

    @Input
    String buildMode

    @Input
    int minSdkVersion

    @Optional @Input
    String localEngine

    @Optional @Input
    String localEngineHost

    @Optional @Input
    String localEngineSrcPath

    @Optional @Input
    Boolean fastStart

    @Input
    String targetPath

    @Optional @Input
    Boolean verbose

    @Optional @Input
    String[] fileSystemRoots

    @Optional @Input
    String fileSystemScheme

    @Input
    Boolean trackWidgetCreation

    @Optional @Input
    List<String> targetPlatformValues

    @Internal
    File sourceDir

    @Internal
    File intermediateDir

    @Optional @Input
    String frontendServerStarterPath

    @Optional @Input
    String extraFrontEndOptions

    @Optional @Input
    String extraGenSnapshotOptions

    @Optional @Input
    String splitDebugInfo

    @Optional @Input
    Boolean treeShakeIcons

    @Optional @Input
    Boolean dartObfuscation

    @Optional @Input
    String dartDefines

    @Optional @Input
    String bundleSkSLPath

    @Optional @Input
    String codeSizeDirectory

    @Optional @Input
    String performanceMeasurementFile

    @Optional @Input
    Boolean deferredComponents

    @Optional @Input
    Boolean validateDeferredComponents

    @Optional @Input
    Boolean skipDependencyChecks
    @Optional @Input
    String flavor

    @OutputFiles
    FileCollection getDependenciesFiles() {
        FileCollection depfiles = project.files()

        // Includes all sources used in the flutter compilation.
        depfiles += project.files("${intermediateDir}/flutter_build.d")
        return depfiles
    }

    void buildBundle() {
        if (!sourceDir.isDirectory()) {
            throw new GradleException("Invalid Flutter source directory: ${sourceDir}")
        }

        intermediateDir.mkdirs()

        // Compute the rule name for flutter assemble. To speed up builds that contain
        // multiple ABIs, the target name is used to communicate which ones are required
        // rather than the TargetPlatform. This allows multiple builds to share the same
        // cache.
        String[] ruleNames
        if (buildMode == "debug") {
            ruleNames = ["debug_android_application"]
        } else if (deferredComponents) {
            ruleNames = targetPlatformValues.collect { "android_aot_deferred_components_bundle_${buildMode}_$it" }
        } else {
            ruleNames = targetPlatformValues.collect { "android_aot_bundle_${buildMode}_$it" }
        }
        project.exec {
            logging.captureStandardError(LogLevel.ERROR)
            executable(flutterExecutable.absolutePath)
            workingDir(sourceDir)
            if (localEngine != null) {
                args "--local-engine", localEngine
                args "--local-engine-src-path", localEngineSrcPath
            }
            if (localEngineHost != null) {
                args "--local-engine-host", localEngineHost
            }
            if (verbose) {
                args "--verbose"
            } else {
                args "--quiet"
            }
            args("assemble")
            args("--no-version-check")
            args("--depfile", "${intermediateDir}/flutter_build.d")
            args("--output", "${intermediateDir}")
            if (performanceMeasurementFile != null) {
                args("--performance-measurement-file=${performanceMeasurementFile}")
            }
            if (!fastStart || buildMode != "debug") {
                args("-dTargetFile=${targetPath}")
            } else {
                args("-dTargetFile=${Paths.get(flutterRoot.absolutePath, "examples", "splash", "lib", "main.dart")}")
            }
            args("-dTargetPlatform=android")
            args("-dBuildMode=${buildMode}")
            if (trackWidgetCreation != null) {
                args("-dTrackWidgetCreation=${trackWidgetCreation}")
            }
            if (splitDebugInfo != null) {
                args("-dSplitDebugInfo=${splitDebugInfo}")
            }
            if (treeShakeIcons == true) {
                args("-dTreeShakeIcons=true")
            }
            if (dartObfuscation == true) {
                args("-dDartObfuscation=true")
            }
            if (dartDefines != null) {
                args("--DartDefines=${dartDefines}")
            }
            if (bundleSkSLPath != null) {
                args("-dBundleSkSLPath=${bundleSkSLPath}")
            }
            if (codeSizeDirectory != null) {
                args("-dCodeSizeDirectory=${codeSizeDirectory}")
            }
            if (flavor != null) {
                args("-dFlavor=${flavor}")
            }
            if (extraGenSnapshotOptions != null) {
                args("--ExtraGenSnapshotOptions=${extraGenSnapshotOptions}")
            }
            if (frontendServerStarterPath != null) {
                args("-dFrontendServerStarterPath=${frontendServerStarterPath}")
            }
            if (extraFrontEndOptions != null) {
                args("--ExtraFrontEndOptions=${extraFrontEndOptions}")
            }
            args("-dAndroidArchs=${targetPlatformValues.join(' ')}")
            args("-dMinSdkVersion=${minSdkVersion}")
            args(ruleNames)
        }
    }

}

class FlutterTask extends BaseFlutterTask {

    @OutputDirectory
    File getOutputDirectory() {
        return intermediateDir
    }

    @Internal
    String getAssetsDirectory() {
        return "${outputDirectory}/flutter_assets"
    }

    @Internal
    CopySpec getAssets() {
        return project.copySpec {
            from("${intermediateDir}")
            include("flutter_assets/**") // the working dir and its files
        }
    }

    @Internal
    CopySpec getSnapshots() {
        return project.copySpec {
            from("${intermediateDir}")

            if (buildMode == "release" || buildMode == "profile") {
                targetPlatformValues.each {
                    include("${PLATFORM_ARCH_MAP[targetArch]}/app.so")
                }
            }
        }
    }

    FileCollection readDependencies(File dependenciesFile, Boolean inputs) {
        if (dependenciesFile.exists()) {
            // Dependencies file has Makefile syntax:
            //   <target> <files>: <source> <files> <separated> <by> <non-escaped space>
            String depText = dependenciesFile.text
            // So we split list of files by non-escaped(by backslash) space,
            def matcher = depText.split(": ")[inputs ? 1 : 0] =~ /(\\ |[^\s])+/
            // then we replace all escaped spaces with regular spaces
            def depList = matcher.collect{ it[0].replaceAll("\\\\ ", " ") }
            return project.files(depList)
        }
        return project.files()
    }

    @InputFiles
    FileCollection getSourceFiles() {
        FileCollection sources = project.files()
        for (File depfile in getDependenciesFiles()) {
            sources += readDependencies(depfile, true)
        }
        return sources + project.files("pubspec.yaml")
    }

    @OutputFiles
    FileCollection getOutputFiles() {
        FileCollection sources = project.files()
        for (File depfile in getDependenciesFiles()) {
            sources += readDependencies(depfile, false)
        }
        return sources
    }

    @TaskAction
    void build() {
        buildBundle()
    }

}
