import java.nio.file.Path
import java.nio.file.Paths

import com.android.builder.model.AndroidProject
import com.android.build.OutputFile
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.2.1'
    }
}

android {
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}

apply plugin: FlutterPlugin

class FlutterPlugin implements Plugin<Project> {
    // 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 Map baseJar = [:]
    private File flutterRoot
    private File flutterExecutable
    private String localEngine
    private String localEngineSrcPath
    private Properties localProperties
    private File flutterJar

    @Override
    void apply(Project project) {
        project.extensions.create("flutter", FlutterExtension)
        project.afterEvaluate this.&addFlutterTask

        // 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 (splitPerAbi(project)) {
            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(project).each { targetArch ->
            String abiValue = PLATFORM_ARCH_MAP[targetArch]
            project.android {
                packagingOptions {
                    // Prevent the ELF library from getting corrupted.
                    doNotStrip "*/${abiValue}/libapp.so"
                }
                if (splitPerAbi(project)) {
                    splits {
                        abi {
                            include abiValue
                        }
                    }
                }
            }
        }

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

        String flutterRootPath = resolveProperty(project, "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")
        }

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

        if (useLocalEngine(project)) {
            String engineOutPath = project.property('localEngineOut')
            File engineOut = project.file(engineOutPath)
            if (!engineOut.isDirectory()) {
                throw new GradleException('localEngineOut must point to a local engine build')
            }
            Path baseEnginePath = Paths.get(engineOut.absolutePath)
            flutterJar = baseEnginePath.resolve("flutter.jar").toFile()
            if (!flutterJar.isFile()) {
                throw new GradleException("Local engine jar not found: $flutterJar")
            }
            localEngine = engineOut.name
            localEngineSrcPath = engineOut.parentFile.parent
            // The local engine is built for one of the build type.
            // However, we use the same engine for each of the build types.
            project.android.buildTypes.each {
                addApiDependencies(project, it.name, project.files {
                    flutterJar
                })
            }
        } else {
            String basePlatformArch = getBasePlatform(project)
            // This is meant to include the compiled classes only, however it will include `libflutter.so` as well.
            Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
            File debugJar = baseEnginePath.resolve("${basePlatformArch}").resolve("flutter.jar").toFile()
            baseJar["debug"] = debugJar
            if (!debugJar.isFile()) {
                project.exec {
                    executable flutterExecutable.absolutePath
                    args "--suppress-analytics"
                    args "precache"
                }
                if (!debugJar.isFile()) {
                    throw new GradleException("Unable to find flutter.jar in SDK: ${debugJar}")
                }
            }
            baseJar["profile"] = baseEnginePath.resolve("${basePlatformArch}-profile").resolve("flutter.jar").toFile()
            baseJar["release"] = baseEnginePath.resolve("${basePlatformArch}-release").resolve("flutter.jar").toFile()

            // Add flutter.jar dependencies to all <buildType>Api configurations, including custom ones
            // added after applying the Flutter plugin.
            project.android.buildTypes.each {
                def buildMode = buildModeFor(it)
                addApiDependencies(project, it.name, project.files {
                    baseJar[buildMode]
                })
            }
            project.android.buildTypes.whenObjectAdded {
                def buildMode = buildModeFor(it)
                addApiDependencies(project, it.name, project.files {
                    baseJar[buildMode]
                })
            }
        }

        File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins')
        Properties plugins = readPropertiesIfExist(pluginsFile)

        plugins.each { name, _ ->
            def pluginProject = project.rootProject.findProject(":$name")
            if (pluginProject != null) {
                project.dependencies {
                    if (project.getConfigurations().findByName("implementation")) {
                        implementation pluginProject
                    } else {
                        compile pluginProject
                    }
                }
                pluginProject.afterEvaluate {
                    pluginProject.android.buildTypes {
                        profile {
                            initWith debug
                        }
                    }
                }
                pluginProject.afterEvaluate this.&addFlutterJarCompileOnlyDependency
            } else {
                project.logger.error("Plugin project :$name not found. Please update settings.gradle.")
            }
        }
    }

    private String resolveProperty(Project project, 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 static List<String> getTargetPlatforms(Project project) {
        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 static Boolean getBuildShareLibrary(Project project) {
        if (project.hasProperty('build-shared-library')) {
            return project.property('build-shared-library').toBoolean()
        }
        return false;
    }

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

    private static Boolean useLocalEngine(Project project) {
        return project.hasProperty('localEngineOut')
    }

    /**
     * Returns the platform that is used to extract the `libflutter.so` and the .class files.
     *
     * Note: This is only needed to add the .class files.
     * Unfortunately, the engine artifacts include the .class and libflutter.so files.
     */
    private static String getBasePlatform(Project project) {
        if (PLATFORM_ARM64 in getTargetPlatforms(project)) {
            return PLATFORM_ARM64;
        }
        return PLATFORM_ARM32;
    }

    // TODO(blasten): Clean this up.
    private void addFlutterJarCompileOnlyDependency(Project project) {
        if (project.state.failure) {
            return
        }
        project.dependencies {
            if (flutterJar != null) {
                if (project.getConfigurations().findByName("compileOnly")) {
                    compileOnly project.files(flutterJar)
                } else {
                    provided project.files(flutterJar)
                }
            } else {
                assert baseJar["debug"].isFile()
                assert baseJar["profile"].isFile()
                assert baseJar["release"].isFile()

                if (project.getConfigurations().findByName("debugCompileOnly")) {
                    debugCompileOnly project.files(baseJar["debug"])
                    profileCompileOnly project.files(baseJar["profile"])
                    releaseCompileOnly project.files(baseJar["release"])
                } else {
                    debugProvided project.files(baseJar["debug"])
                    profileProvided project.files(baseJar["profile"])
                    releaseProvided project.files(baseJar["release"])
                }
            }
        }
    }

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

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

        Boolean verboseValue = null
        if (project.hasProperty('verbose')) {
            verboseValue = project.property('verbose').toBoolean()
        }
        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 compilationTraceFilePathValue = null
        if (project.hasProperty('compilation-trace-file')) {
            compilationTraceFilePathValue = project.property('compilation-trace-file')
        }
        Boolean createPatchValue = false
        if (project.hasProperty('patch')) {
            createPatchValue = project.property('patch').toBoolean()
        }
        Integer buildNumberValue = null
        if (project.hasProperty('build-number')) {
            buildNumberValue = project.property('build-number').toInteger()
        }
        String baselineDirValue = null
        if (project.hasProperty('baseline-dir')) {
            baselineDirValue = project.property('baseline-dir')
        }
        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')
        }

        def targetPlatforms = getTargetPlatforms(project)
        def addFlutterDeps = { variant ->
            if (splitPerAbi(project)) {
                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 flutterBuildMode = buildModeFor(variant.buildType)
            if (flutterBuildMode == 'debug' && project.tasks.findByName("${FLUTTER_BUILD_PREFIX}X86Jar")) {
                Task task = project.tasks.findByName("compile${variant.name.capitalize()}JavaWithJavac")
                if (task) {
                    task.dependsOn project.flutterBuildX86Jar
                }
                task = project.tasks.findByName("compile${variant.name.capitalize()}Kotlin")
                if (task) {
                    task.dependsOn project.flutterBuildX86Jar
                }
            }

            def flutterTasks = []
            targetPlatforms.each { targetArch ->
                String abiValue = PLATFORM_ARCH_MAP[targetArch]
                String taskName = "compile${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}${targetArch.replace('android-', '').capitalize()}"
                FlutterTask compileTask = project.tasks.create(name: taskName, type: FlutterTask) {
                    flutterRoot this.flutterRoot
                    flutterExecutable this.flutterExecutable
                    buildMode flutterBuildMode
                    localEngine this.localEngine
                    localEngineSrcPath this.localEngineSrcPath
                    abi abiValue
                    targetPath target
                    verbose verboseValue
                    fileSystemRoots fileSystemRootsValue
                    fileSystemScheme fileSystemSchemeValue
                    trackWidgetCreation trackWidgetCreationValue
                    compilationTraceFilePath compilationTraceFilePathValue
                    createPatch createPatchValue
                    buildNumber buildNumberValue
                    baselineDir baselineDirValue
                    targetPlatform targetArch
                    sourceDir project.file(project.flutter.source)
                    intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/${targetArch}")
                    extraFrontEndOptions extraFrontEndOptionsValue
                    extraGenSnapshotOptions extraGenSnapshotOptionsValue
                }
                flutterTasks.add(compileTask)
            }
            def libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar")
            def libFlutterPlatforms = targetPlatforms.collect()
            // x86/x86_64 native library used for debugging only, for now.
            if (flutterBuildMode == 'debug') {
                libFlutterPlatforms.add('android-x86')
                libFlutterPlatforms.add('android-x64')
            }
            Task packFlutterSnapshotsAndLibsTask = project.tasks.create(name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) {
                destinationDir libJar.parentFile
                archiveName libJar.name
                libFlutterPlatforms.each { targetArch ->
                    // This check prevents including `libflutter.so` twice, since it's included in the base platform jar.
                    // Unfortunately, the `pickFirst` setting in `packagingOptions` does not work when the project `:flutter`
                    // is included as an implementation dependency, which causes duplicated `libflutter.so`.
                    if (getBasePlatform(project) == targetArch) {
                        return
                    }
                    // Don't include `libflutter.so` for other architectures when a local engine is specified.
                    if (useLocalEngine(project)) {
                        return
                    }
                    def engineArtifactSubdir = getEngineArtifactDirName(variant.buildType, targetArch);
                    // Include `libflutter.so`.
                    // TODO(blasten): The libs should be outside `flutter.jar` when the artifacts are downloaded.
                    from(project.zipTree("${flutterRoot}/bin/cache/artifacts/engine/${engineArtifactSubdir}/flutter.jar")) {
                        include 'lib/**'
                    }
                }
                dependsOn flutterTasks
                // Add the ELF library.
                flutterTasks.each { flutterTask ->
                    from(flutterTask.intermediateDir) {
                        include '*.so'
                        rename { String filename ->
                            return "lib/${flutterTask.abi}/lib${filename}"
                        }
                    }
                }
            }
            // Include the snapshots and libflutter.so in `lib/`.
            addApiDependencies(project, variant.name, project.files {
                packFlutterSnapshotsAndLibsTask
            })

            // We know that the flutter app is a subproject in another Android app when these tasks exist.
            Task packageAssets = project.tasks.findByPath(":flutter:package${variant.name.capitalize()}Assets")
            Task cleanPackageAssets = project.tasks.findByPath(":flutter:cleanPackage${variant.name.capitalize()}Assets")
            Task copyFlutterAssetsTask = project.tasks.create(name: "copyFlutterAssets${variant.name.capitalize()}", type: Copy) {
                dependsOn flutterTasks
                if (packageAssets && cleanPackageAssets) {
                    dependsOn packageAssets
                    dependsOn cleanPackageAssets
                    into packageAssets.outputDir
                } else {
                    dependsOn variant.mergeAssets
                    dependsOn "clean${variant.mergeAssets.name.capitalize()}"
                    variant.mergeAssets.mustRunAfter("clean${variant.mergeAssets.name.capitalize()}")
                    into variant.mergeAssets.outputDir
                }
                flutterTasks.each { flutterTask ->
                    with flutterTask.assets
                }
            }
            if (packageAssets) {
                String mainModuleName = "app"
                try {
                    String tmpModuleName = project.rootProject.ext.mainModuleName
                    if (tmpModuleName != null && !tmpModuleName.empty) {
                        mainModuleName = tmpModuleName
                    }
                } catch (Exception e) {
                }
                // Only include configurations that exist in parent project.
                Task mergeAssets = project.tasks.findByPath(":${mainModuleName}:merge${variant.name.capitalize()}Assets")
                if (mergeAssets) {
                    mergeAssets.dependsOn(copyFlutterAssetsTask)
                }
            } else {
                def processResources = variant.outputs.first().processResources
                processResources.dependsOn(copyFlutterAssetsTask)
            }
        }

        if (project.android.hasProperty("applicationVariants")) {
            project.android.applicationVariants.all addFlutterDeps
        } else {
            project.android.libraryVariants.all addFlutterDeps
        }
    }
}

class FlutterExtension {
    String source
    String target
}

abstract class BaseFlutterTask extends DefaultTask {
    File flutterRoot
    File flutterExecutable
    String buildMode
    String localEngine
    String localEngineSrcPath
    @Input
    String targetPath
    @Optional @Input
    Boolean verbose
    @Optional @Input
    String[] fileSystemRoots
    @Optional @Input
    String fileSystemScheme
    @Input
    Boolean trackWidgetCreation
    @Optional @Input
    String compilationTraceFilePath
    @Optional @Input
    Boolean createPatch
    @Optional @Input
    Integer buildNumber
    @Optional @Input
    String baselineDir
    @Optional @Input
    String targetPlatform
    @Input
    String abi
    File sourceDir
    File intermediateDir
    @Optional @Input
    String extraFrontEndOptions
    @Optional @Input
    String extraGenSnapshotOptions

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

        // Include the kernel compiler depfile, since kernel compile is the
        // first stage of AOT build in this mode, and it includes all the Dart
        // sources.
        depfiles += project.files("${intermediateDir}/kernel_compile.d")

        // Include Core JIT kernel compiler depfile, since kernel compile is
        // the first stage of JIT builds in this mode, and it includes all the
        // Dart sources.
        depfiles += project.files("${intermediateDir}/snapshot_blob.bin.d")
        return depfiles
    }

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

        intermediateDir.mkdirs()

        if (buildMode == "profile" || buildMode == "release") {
            project.exec {
                executable flutterExecutable.absolutePath
                workingDir sourceDir
                if (localEngine != null) {
                    args "--local-engine", localEngine
                    args "--local-engine-src-path", localEngineSrcPath
                }
                args "build", "aot"
                args "--suppress-analytics"
                args "--quiet"
                args "--build-shared-library"
                args "--target", targetPath
                args "--output-dir", "${intermediateDir}"
                args "--target-platform", "${targetPlatform}"
                if (trackWidgetCreation) {
                    args "--track-widget-creation"
                }
                if (extraFrontEndOptions != null) {
                    args "--extra-front-end-options", "${extraFrontEndOptions}"
                }
                if (extraGenSnapshotOptions != null) {
                    args "--extra-gen-snapshot-options", "${extraGenSnapshotOptions}"
                }
                args "--${buildMode}"
            }
        }

        project.exec {
            executable flutterExecutable.absolutePath
            workingDir sourceDir
            if (localEngine != null) {
                args "--local-engine", localEngine
                args "--local-engine-src-path", localEngineSrcPath
            }
            args "build", "bundle"
            args "--target", targetPath
            args "--target-platform", "${targetPlatform}"
            if (verbose) {
                args "--verbose"
            }
            if (fileSystemRoots != null) {
                for (root in fileSystemRoots) {
                    args "--filesystem-root", root
                }
            }
            if (fileSystemScheme != null) {
                args "--filesystem-scheme", fileSystemScheme
            }
            if (trackWidgetCreation) {
                args "--track-widget-creation"
            }
            if (compilationTraceFilePath != null) {
                args "--compilation-trace-file", compilationTraceFilePath
            }
            if (createPatch) {
                args "--patch"
                args "--build-number", project.android.defaultConfig.versionCode
                if (buildNumber != null) {
                    assert buildNumber == project.android.defaultConfig.versionCode
                }
            }
            if (baselineDir != null) {
                args "--baseline-dir", baselineDir
            }
            if (extraFrontEndOptions != null) {
                args "--extra-front-end-options", "${extraFrontEndOptions}"
            }
            if (extraGenSnapshotOptions != null) {
                args "--extra-gen-snapshot-options", "${extraGenSnapshotOptions}"
            }
            if (buildMode == "release" || buildMode == "profile") {
                args "--precompiled"
            } else {
                args "--depfile", "${intermediateDir}/snapshot_blob.bin.d"
            }
            args "--asset-dir", "${intermediateDir}/flutter_assets"
            if (buildMode == "debug") {
                args "--debug"
            }
            if (buildMode == "profile") {
                args "--profile"
            }
            if (buildMode == "release") {
                args "--release"
            }
        }
    }
}

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

    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') {
                include "app.so"
            }
        }
    }

    FileCollection readDependencies(File dependenciesFile) {
        if (dependenciesFile.exists()) {
            try {
                // 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(': ')[1] =~ /(\\ |[^\s])+/
                // then we replace all escaped spaces with regular spaces
                def depList = matcher.collect{it[0].replaceAll("\\\\ ", " ")}
                return project.files(depList)
            } catch (Exception e) {
                logger.error("Error reading dependency file ${dependenciesFile}: ${e}")
            }
        }
        return project.files()
    }

    @InputFiles
    FileCollection getSourceFiles() {
        FileCollection sources = project.files()
        for (File depfile in getDependenciesFiles()) {
          sources += readDependencies(depfile)
        }
        if (!sources.isEmpty()) {
            // We have a dependencies file. Add a dependency on gen_snapshot as well, since the
            // snapshots have to be rebuilt if it changes.
            sources += readDependencies(project.file("${intermediateDir}/gen_snapshot.d"))
            sources += readDependencies(project.file("${intermediateDir}/frontend_server.d"))
            if (localEngineSrcPath != null) {
                sources += project.files("$localEngineSrcPath/$localEngine")
            }
            // Finally, add a dependency on pubspec.yaml as well.
            return sources + project.files('pubspec.yaml')
        }
        // No dependencies file (or problems parsing it). Fall back to source files.
        return project.fileTree(
                dir: sourceDir,
                exclude: ['android', 'ios'],
                include: ['**/*.dart', 'pubspec.yaml']
        )
    }

    @TaskAction
    void build() {
        buildBundle()
    }
}

gradle.useLogger(new FlutterEventLogger())

class FlutterEventLogger extends BuildAdapter implements TaskExecutionListener {
    String mostRecentTask = ""

    void beforeExecute(Task task) {
        mostRecentTask = task.name
    }

    void afterExecute(Task task, TaskState state) {}

    void buildFinished(BuildResult result) {
        if (result.failure != null) {
            if (!(result.failure instanceof GradleException) || !mostRecentTask.startsWith(FlutterPlugin.FLUTTER_BUILD_PREFIX)) {
                result.rethrowFailure()
            }
        }
    }
}
