import static groovy.io.FileType.FILES

import com.android.builder.model.AndroidProject
import com.android.build.OutputFile
import groovy.json.JsonSlurper
import java.nio.file.Path
import java.nio.file.Paths
import java.util.regex.Matcher
import java.util.regex.Pattern
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
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.tasks.Copy
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.bundling.Jar

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.0'
    }
}

android {
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}

apply plugin: FlutterPlugin

class FlutterPlugin implements Plugin<Project> {
    private static final String MAVEN_REPO      = "https://storage.googleapis.com/download.flutter.io";

    // 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.
    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";

    // 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 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,
    ]

    // 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 Map baseJar = [:]
    private File flutterRoot
    private File flutterExecutable
    private String localEngine
    private String localEngineSrcPath
    private Properties localProperties
    private String engineVersion

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

        project.extensions.create("flutter", FlutterExtension)
        project.afterEvaluate this.&addFlutterTasks
        // 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
                    }
                }
            }
        }
        getTargetPlatforms().each { targetArch ->
            String abiValue = PLATFORM_ARCH_MAP[targetArch]
            project.android {
                if (shouldSplitPerAbi()) {
                    splits {
                        abi {
                            include abiValue
                        }
                    }
                }
            }
        }

        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()

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

        // Add custom build types.
        project.android.buildTypes {
            profile {
                initWith debug
                if (it.hasProperty("matchingFallbacks")) {
                    matchingFallbacks = ["debug", "release"]
                }
            }
        }

        if (shouldShrinkResources(project)) {
            String flutterProguardRules = Paths.get(flutterRoot.absolutePath, "packages", "flutter_tools",
                    "gradle", "flutter_proguard_rules.pro")
            project.android.buildTypes {
                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.
                    // NOTE: 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
        }
        project.android.buildTypes.each this.&addFlutterDependencies
        project.android.buildTypes.whenObjectAdded this.&addFlutterDependencies
    }

    /**
     * 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
        }
        String repository = useLocalEngine()
            ? project.property('local-engine-repo')
            : MAVEN_REPO

        project.rootProject.allprojects {
            repositories {
                maven {
                    url repository
                }
            }
        }
        // Add the embedding dependency.
        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")
        }
    }

    /**
     * Returns the directory where the plugins are built.
     */
    private File getPluginBuildDir() {
        // Module projects specify this flag to include plugins in the same repo as the module project.
        if (project.ext.has("pluginBuildDir")) {
            return project.ext.get("pluginBuildDir")
        }
        return project.buildDir
    }

    /**
     * Configures the Flutter plugin dependencies.
     *
     * The plugins are added to pubspec.yaml. Then, upon running `flutter pub get`,
     * the tool generates a `.flutter-plugins` file, which contains a 1:1 map to each plugin location.
     * Finally, the project's `settings.gradle` loads each plugin's android directory as a subproject.
     */
    private void configurePlugins() {
        if (!buildPluginAsAar()) {
            getPluginList().each this.&configurePluginProject
            getPluginDependencies().each this.&configurePluginDependencies
            return
        }
        project.repositories {
            maven {
                url "${getPluginBuildDir()}/outputs/repo"
            }
        }
        getPluginList().each { pluginName, pluginPath ->
            configurePluginAar(pluginName, pluginPath, project)
        }
    }

    private static final Pattern GROUP_PATTERN = ~/group\s+\'(.+)\'/
    private static final Pattern PROJECT_NAME_PATTERN = ~/rootProject\.name\s+=\s+\'(.+)\'/

    // Adds the plugin AAR dependency to the app project.
    private void configurePluginAar(String pluginName, String pluginPath, Project project) {
        // Extract the group id from the plugin's build.gradle.
        // This is `group '<group-id>'`
        File pluginBuildFile = project.file(Paths.get(pluginPath, "android", "build.gradle"));
        if (!pluginBuildFile.exists()) {
            throw new GradleException("Plugin $pluginName doesn't have the required file $pluginBuildFile.")
        }

        Matcher groupParts = GROUP_PATTERN.matcher(pluginBuildFile.text)
        assert groupParts.count == 1
        assert groupParts.hasGroup()
        String groupId = groupParts[0][1]

        // Extract the artifact name from the plugin's settings.gradle.
        // This is `rootProject.name = '<artifact-name>'`
        File pluginSettings = project.file(Paths.get(pluginPath, "android", "settings.gradle"));
        if (!pluginSettings.exists()) {
            throw new GradleException("Plugin $pluginName doesn't have the required file $pluginSettings.")
        }
        Matcher projectNameParts = PROJECT_NAME_PATTERN.matcher(pluginSettings.text)
        assert projectNameParts.count == 1
        assert projectNameParts.hasGroup()
        String artifactId = "${projectNameParts[0][1]}_release"

        assert !groupId.empty
        project.dependencies.add("api", "$groupId:$artifactId:+")
    }

    // Adds the plugin project dependency to the app project .
    private void configurePluginProject(String pluginName, String _) {
        Project pluginProject = project.rootProject.findProject(":$pluginName")
        if (pluginProject == null) {
            project.logger.error("Plugin project :$pluginName not found. Please update settings.gradle.")
            return
        }
        // Add plugin dependency to the app project.
        project.dependencies {
            implementation pluginProject
        }
        Closure addEmbeddingCompileOnlyDependency = { 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
            }
            addApiDependencies(
                pluginProject,
                buildType.name,
                "io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion"
            )
        }
        pluginProject.afterEvaluate {
            pluginProject.android.buildTypes {
                profile {
                    initWith debug
                }
            }
            pluginProject.android.buildTypes.each addEmbeddingCompileOnlyDependency
            pluginProject.android.buildTypes.whenObjectAdded addEmbeddingCompileOnlyDependency
        }
    }

    // Returns `true` if the given path contains an `android/build.gradle` file.
    //
    // TODO(egarciad): Fix https://github.com/flutter/flutter/issues/39657.
    // Android Studio may create empty android directories due to the logic in <app>/android/settings.gradle,
    // which imports all plugins regardless of whether they support the android platform.
    private Boolean doesSupportAndroidPlatform(String path) {
        File editableAndroidProject = new File(path, 'android' + File.separator + 'build.gradle')
        return editableAndroidProject.exists()
    }

    // 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(Object dependencyObject) {
        assert dependencyObject.name instanceof String
        Project pluginProject = project.rootProject.findProject(":${dependencyObject.name}")
        if (pluginProject == null ||
            !doesSupportAndroidPlatform(pluginProject.projectDir.parentFile.path)) {
            return
        }
        assert dependencyObject.dependencies instanceof List
        dependencyObject.dependencies.each { pluginDependencyName ->
            assert pluginDependencyName instanceof String
            if (pluginDependencyName.empty) {
                return
            }
            Project dependencyProject = project.rootProject.findProject(":$pluginDependencyName")
            if (dependencyProject == null ||
                !doesSupportAndroidPlatform(dependencyProject.projectDir.parentFile.path)) {
                return
            }
            // Wait for the Android plugin to load and add the dependency to the plugin project.
            pluginProject.afterEvaluate {
                pluginProject.dependencies {
                    implementation dependencyProject
                }
            }
        }
    }

    private Properties getPluginList() {
        File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins')
        Properties allPlugins = readPropertiesIfExist(pluginsFile)
        Properties androidPlugins = new Properties()
        allPlugins.each { name, path ->
            if (doesSupportAndroidPlatform(path)) {
                androidPlugins.setProperty(name, path)
            }
            // TODO(amirh): log an error if this plugin was specified to be an Android
            // plugin according to the new schema, and was missing a build.gradle file.
            // https://github.com/flutter/flutter/issues/40784
        }
        return androidPlugins
    }

    // Gets the plugins dependencies from `.flutter-plugins-dependencies`.
    private List getPluginDependencies() {
        // Consider a `.flutter-plugins-dependencies` file with the following content:
        // {
        //     "dependencyGraph": [
        //       {
        //         "name": "plugin-a",
        //         "dependencies": ["plugin-b","plugin-c"]
        //       },
        //       {
        //         "name": "plugin-b",
        //         "dependencies": ["plugin-c"]
        //       },
        //       {
        //         "name": "plugin-c",
        //         "dependencies": []'
        //       }
        //     ]
        //  }
        //
        // This means, `plugin-a` depends on `plugin-b` and `plugin-c`.
        // `plugin-b` depends on `plugin-c`.
        // `plugin-c` doesn't depend on anything.
        File pluginsDependencyFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins-dependencies')
        if (pluginsDependencyFile.exists()) {
            def object = new JsonSlurper().parseText(pluginsDependencyFile.text)
            assert object instanceof Map
            assert object.dependencyGraph instanceof List
            return object.dependencyGraph
        }
        return []
    }

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

    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 static Properties readPropertiesIfExist(File propertiesFile) {
        Properties result = new Properties()
        if (propertiesFile.exists()) {
            propertiesFile.withReader('UTF-8') { reader -> result.load(reader) }
        }
        return result
    }

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

    private Boolean shouldSplitPerAbi() {
        if (project.hasProperty('split-per-abi')) {
            return project.property('split-per-abi').toBoolean()
        }
        return false;
    }

    private Boolean useLocalEngine() {
        return project.hasProperty('local-engine-repo')
    }

    private Boolean isVerbose() {
        if (project.hasProperty('verbose')) {
            return project.property('verbose').toBoolean()
        }
        return false
    }

    /// Whether to build the debug app in "fast-start" mode.
    private Boolean isFastStart() {
        if (project.hasProperty("fast-start")) {
            return project.property("fast-start").toBoolean()
        }
        return false
    }


    private static Boolean shouldShrinkResources(Project project) {
        if (project.hasProperty("shrink")) {
            return project.property("shrink").toBoolean()
        }
        return false
    }

    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 Boolean buildPluginAsAar() {
        return System.getProperty('build-plugins-as-aars') == 'true'
    }

    // 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;
        }
        assert project.hasProperty('local-engine-build-mode')
        // Don't configure dependencies for a build mode that the local engine
        // doesn't support.
        return project.property('local-engine-build-mode') == flutterBuildMode
    }

    private void addCompileOnlyDependency(Project project, String variantName, Object dependency, Closure config = null) {
        if (project.state.failure) {
            return
        }
        String configuration;
        if (project.getConfigurations().findByName("compileOnly")) {
            configuration = "${variantName}CompileOnly";
        } else {
            configuration = "${variantName}Provided";
        }
        project.dependencies.add(configuration, dependency, config)
    }

    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)
    }

    /**
     * Returns a Flutter build mode suitable for the specified Android buildType.
     *
     * Note: 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"
    }

    private static String getEngineArtifactDirName(buildType, targetArch) {
        if (buildType.name == "profile") {
            return "${targetArch}-profile"
        } else if (buildType.debuggable) {
            return "${targetArch}"
        }
        return "${targetArch}-release"
    }

    private void addFlutterTasks(Project project) {
        if (project.state.failure) {
            return
        }
        if (project.flutter.source == null) {
            throw new GradleException("Must provide Flutter source directory")
        }
        String target = project.flutter.target
        if (target == null) {
            target = 'lib/main.dart'
        }
        if (project.hasProperty('target')) {
            target = project.property('target')
        }
        String[] fileSystemRootsValue = null
        if (project.hasProperty('filesystem-roots')) {
            fileSystemRootsValue = project.property('filesystem-roots').split('\\|')
        }
        String fileSystemSchemeValue = null
        if (project.hasProperty('filesystem-scheme')) {
            fileSystemSchemeValue = project.property('filesystem-scheme')
        }
        Boolean trackWidgetCreationValue = false
        if (project.hasProperty('track-widget-creation')) {
            trackWidgetCreationValue = project.property('track-widget-creation').toBoolean()
        }
        String extraFrontEndOptionsValue = null
        if (project.hasProperty('extra-front-end-options')) {
            extraFrontEndOptionsValue = project.property('extra-front-end-options')
        }
        String extraGenSnapshotOptionsValue = null
        if (project.hasProperty('extra-gen-snapshot-options')) {
            extraGenSnapshotOptionsValue = project.property('extra-gen-snapshot-options')
        }
        String splitDebugInfoValue = null
        if (project.hasProperty('split-debug-info')) {
            splitDebugInfoValue = project.property('split-debug-info')
        }
        Boolean dartObfuscationValue = false
        if (project.hasProperty('dart-obfuscation')) {
            dartObfuscationValue = project.property('dart-obfuscation').toBoolean();
        }
        Boolean treeShakeIconsOptionsValue = false
        if (project.hasProperty('tree-shake-icons')) {
            treeShakeIconsOptionsValue = project.property('tree-shake-icons').toBoolean()
        }
        def 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
                    def abiVersionCode = ABI_VERSION.get(output.getFilter(OutputFile.ABI))
                    if (abiVersionCode != null) {
                        output.versionCodeOverride =
                            abiVersionCode * 1000 + variant.versionCode
                    }
                }
            }
            String variantBuildMode = buildModeFor(variant.buildType)
            String taskName = toCammelCase(["compile", FLUTTER_BUILD_PREFIX, variant.name])
            FlutterTask compileTask = project.tasks.create(name: taskName, type: FlutterTask) {
                flutterRoot this.flutterRoot
                flutterExecutable this.flutterExecutable
                buildMode variantBuildMode
                localEngine this.localEngine
                localEngineSrcPath this.localEngineSrcPath
                targetPath target
                verbose isVerbose()
                fastStart isFastStart()
                fileSystemRoots fileSystemRootsValue
                fileSystemScheme fileSystemSchemeValue
                trackWidgetCreation trackWidgetCreationValue
                targetPlatformValues = targetPlatforms
                sourceDir project.file(project.flutter.source)
                intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/")
                extraFrontEndOptions extraFrontEndOptionsValue
                extraGenSnapshotOptions extraGenSnapshotOptionsValue
                splitDebugInfo splitDebugInfoValue
                treeShakeIcons treeShakeIconsOptionsValue
                dartObfuscation dartObfuscationValue
                doLast {
                    project.exec {
                        if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                            commandLine('cmd', '/c', "attrib -r ${assetsDirectory}/* /s")
                        } else {
                            commandLine('chmod', '-R', 'u+w', assetsDirectory)
                        }
                    }
                }
            }
            File libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar")
            Task packFlutterAppAotTask = project.tasks.create(name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) {
                destinationDir libJar.parentFile
                archiveName 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}"
                        }
                    }
                }
            }
            addApiDependencies(project, variant.name, project.files {
                packFlutterAppAotTask
            })
            // We 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.
            // We know that `:flutter` is used as a subproject when these tasks exists and we aren'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
            Task copyFlutterAssetsTask = project.tasks.create(
                name: "copyFlutterAssets${variant.name.capitalize()}",
                type: Copy,
            ) {
                dependsOn compileTask
                with compileTask.assets
                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("processResourcesProvider") ?
                    variantOutput.processResourcesProvider.get() : variantOutput.processResources
                processResources.dependsOn(copyFlutterAssetsTask)
                return
            }
            // Flutter module included as a subproject in add to app.
            Project appProject = project.rootProject.findProject(':app')
            assert appProject != null
            appProject.afterEvaluate {
                assert appProject.android != null
                appProject.android.applicationVariants.all { appProjectVariant ->
                    // 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     |   relese                      |
                    // |   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`.
                    if (buildModeFor(appProjectVariant.buildType) != variantBuildMode) {
                        return
                    }
                    Task mergeAssets = project
                        .tasks
                        .findByPath(":app:merge${appProjectVariant.name.capitalize()}Assets")
                    assert mergeAssets
                    mergeAssets.dependsOn(copyFlutterAssetsTask)
                }
            }
        }
        if (project.android.hasProperty("applicationVariants")) {
            project.android.applicationVariants.all addFlutterDeps
        } else {
            project.android.libraryVariants.all addFlutterDeps
        }
        configurePlugins()
    }
}

class FlutterExtension {
    String source
    String target
}

abstract class BaseFlutterTask extends DefaultTask {
    File flutterRoot
    File flutterExecutable
    String buildMode
    @Optional @Input
    String localEngine
    @Optional @Input
    String localEngineSrcPath
    @Input
    Boolean fastStart
    @Input
    String targetPath
    @Optional
    Boolean verbose
    @Optional @Input
    String[] fileSystemRoots
    @Optional @Input
    String fileSystemScheme
    @Input
    Boolean trackWidgetCreation
    @Optional @Input
    List<String> targetPlatformValues
    File sourceDir
    File intermediateDir
    @Optional @Input
    String extraFrontEndOptions
    @Optional @Input
    String extraGenSnapshotOptions
    @Optional @Input
    String splitDebugInfo
    @Optional @Input
    Boolean treeShakeIcons
    @Optional @Input
    Boolean dartObfuscation

    @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") {
            if (fastStart) {
                ruleNames = ["faststart_android_application"]
            } else {
                ruleNames = ["debug_android_application"]
            }
        } else {
            ruleNames = targetPlatformValues.collect { "android_aot_bundle_${buildMode}_$it" }
        }
        project.exec {
            executable flutterExecutable.absolutePath
            workingDir sourceDir
            if (localEngine != null) {
                args "--local-engine", localEngine
                args "--local-engine-src-path", localEngineSrcPath
            }
            if (verbose) {
                args "--verbose"
            } else {
                args "--quiet"
            }
            args "assemble"
            args "--depfile", "${intermediateDir}/flutter_build.d"
            args "--output", "${intermediateDir}"
            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 (extraFrontEndOptions != null) {
                args "-dExtraFrontEndOptions=${extraFrontEndOptions}"
            }
            if (splitDebugInfo != null) {
                args "-dSplitDebugInfo=${splitDebugInfo}"
            }
            if (treeShakeIcons == true) {
                args "-dTreeShakeIcons=true"
            }
            if (dartObfuscation == true) {
                args "-dDartObfuscation=true"
            }
            if (extraGenSnapshotOptions != null) {
                args "--ExtraGenSnapshotOptions=${extraGenSnapshotOptions}"
            }
            args ruleNames
        }
    }
}

class FlutterTask extends BaseFlutterTask {
    @OutputDirectory
    File getOutputDirectory() {
        return intermediateDir
    }

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

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

    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()
    }
}
