/* 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
                    int 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()
    }

}
