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

import com.android.builder.model.AndroidProject
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> {
    private Path baseEnginePath
    private File flutterRoot
    private File flutterExecutable
    private String localEngine
    private String localEngineSrcPath
    private Properties localProperties
    private File flutterJar
    private File debugFlutterJar
    private File profileFlutterJar
    private File releaseFlutterJar
    private File dynamicProfileFlutterJar
    private File dynamicReleaseFlutterJar

    // 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 flutterBuildPrefix = "flutterBuild"

    // The platforms (or CPU architectures) for which native code is generated.
    static final Map allTargetPlatforms = [
        'android-arm': 'armeabi-v7a',
        'android-arm64': 'arm64-v8a',
        'android-x64': 'x86_64',
        'android-x86': 'x86',
    ]

    // Supports ARM 32 and 64 bits.
    // When splits are enabled, multiple APKs are generated per each CPU architecture,
    // which helps decrease the size of each APK.
    static final Set allArmPlatforms = [
        'android-arm',
        'android-arm64'
    ]

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

    private String getTargetPlatform(Project project) {
        if (project.hasProperty('target-platform')) {
            return project.property('target-platform')
        }
        return 'android-arm-all';
    }

    private Boolean getBuildShareLibrary(Project project) {
        if (project.hasProperty('build-shared-library')) {
            return project.property('build-shared-library').toBoolean()
        }
        return false;
    }

    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
    }

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

        allTargetPlatforms.each { currentTargetPlatformValue, abi ->
            project.android {
                packagingOptions {
                    pickFirst "lib/${abi}/libflutter.so"

                    // Disable warning by *-android-strip: File format not recognized
                    doNotStrip "*/${abi}/lib_vm_snapshot_data.so"
                    doNotStrip "*/${abi}/lib_vm_snapshot_instr.so"
                    doNotStrip "*/${abi}/lib_isolate_snapshot_data.so"
                    doNotStrip "*/${abi}/lib_isolate_snapshot_instr.so"
                }
            }
        }

        // Add custom build types
        project.android.buildTypes {
            profile {
                initWith debug
                if (it.hasProperty('matchingFallbacks')) {
                    matchingFallbacks = ['debug', 'release']
                }
            }
            dynamicProfile {
                initWith debug
                if (it.hasProperty('matchingFallbacks')) {
                    matchingFallbacks = ['debug', 'release']
                }
            }
            dynamicRelease {
                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 (project.hasProperty('localEngineOut')) {
            String engineOutPath = project.property('localEngineOut')
            File engineOut = project.file(engineOutPath)
            if (!engineOut.isDirectory()) {
                throw new GradleException('localEngineOut must point to a local engine build')
            }
            baseEnginePath = Paths.get(engineOut.absolutePath)
            flutterJar = baseEnginePath.resolve("flutter.jar").toFile()
            if (!flutterJar.isFile()) {
                throw new GradleException('File 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.
            debugFlutterJar = flutterJar
            profileFlutterJar = flutterJar
            releaseFlutterJar = flutterJar
            dynamicProfileFlutterJar = flutterJar
            dynamicReleaseFlutterJar = flutterJar
        } else {
            String targetPlatform = getTargetPlatform(project)
            String targetArch = targetPlatform == 'android-arm64' ? 'arm64' : 'arm'
            baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
            debugFlutterJar = baseEnginePath.resolve("android-${targetArch}").resolve("flutter.jar").toFile()
            profileFlutterJar = baseEnginePath.resolve("android-${targetArch}-profile").resolve("flutter.jar").toFile()
            releaseFlutterJar = baseEnginePath.resolve("android-${targetArch}-release").resolve("flutter.jar").toFile()
            dynamicProfileFlutterJar = baseEnginePath.resolve("android-${targetArch}-dynamic-profile").resolve("flutter.jar").toFile()
            dynamicReleaseFlutterJar = baseEnginePath.resolve("android-${targetArch}-dynamic-release").resolve("flutter.jar").toFile()
        }

        if (!debugFlutterJar.isFile()) {
            project.exec {
                executable flutterExecutable.absolutePath
                args "--suppress-analytics"
                args "precache"
            }
            if (!debugFlutterJar.isFile()) {
                throw new GradleException("Unable to find flutter.jar in SDK: ${debugFlutterJar}")
            }
        }

        // Add x86/x86_64 native library. Debug mode only, for now.
        File flutterX86Jar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/flutter-x86.jar")
        Task debugX86JarTask = project.tasks.create("${flutterBuildPrefix}X86Jar", Jar) {
            destinationDir flutterX86Jar.parentFile
            archiveName flutterX86Jar.name
            from("${flutterRoot}/bin/cache/artifacts/engine/android-x86/libflutter.so") {
                into 'lib/x86'
            }
            from("${flutterRoot}/bin/cache/artifacts/engine/android-x64/libflutter.so") {
                into 'lib/x86_64'
            }
        }
        // Add flutter.jar dependencies to all <buildType>Api configurations, including custom ones
        // added after applying the Flutter plugin.
        project.android.buildTypes.each { 
            addFlutterJarApiDependency(project, it, debugX86JarTask)
        }
        project.android.buildTypes.whenObjectAdded {
            addFlutterJarApiDependency(project, it, debugX86JarTask)
        }

        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 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 {
                if (project.getConfigurations().findByName("debugCompileOnly")) {
                    debugCompileOnly project.files(debugFlutterJar)
                    profileCompileOnly project.files(profileFlutterJar)
                    releaseCompileOnly project.files(releaseFlutterJar)
                } else {
                    debugProvided project.files(debugFlutterJar)
                    profileProvided project.files(profileFlutterJar)
                    releaseProvided project.files(releaseFlutterJar)
                }
            }
        }
    }

    /**
     * Adds suitable flutter.jar api dependencies to the specified buildType.
     *
     * Note: The BuildType DSL type is not public, and is therefore omitted from the signature.
     */
    private void addFlutterJarApiDependency(Project project, buildType, Task debugX86JarTask) {
        project.dependencies {
            String configuration;
            if (project.getConfigurations().findByName("api")) {
                configuration = buildType.name + "Api";
            } else {
                configuration = buildType.name + "Compile";
            }
            add(configuration, project.files {
                String buildMode = buildModeFor(buildType)
                switch (buildMode) {
                    case "debug":
                        [debugX86JarTask, debugFlutterJar]
                    break
                    case "profile":
                        profileFlutterJar
                        break
                    case "dynamicProfile":
                        dynamicProfileFlutterJar
                        break
                    case "dynamicRelease":
                        dynamicReleaseFlutterJar
                        break
                    case "release":
                        releaseFlutterJar
                        break
                    default:
                        throw new GradleException("Invalid build mode: ${buildMode}")
                }
            })
        }
    }

    /**
     * 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", "dynamicProfile", "dynamicRelease", or "release" (fall-back).
     */
    private static String buildModeFor(buildType) {
        if (buildType.name == "profile") {
            return "profile"
        } else if (buildType.name == "dynamicProfile") {
            return "dynamicProfile"
        } else if (buildType.name == "dynamicRelease") {
            return "dynamicRelease"
        } else if (buildType.debuggable) {
            return "debug"
        }
        return "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')
        }

        Boolean buildSharedLibraryValue = this.getBuildShareLibrary(project)
        String targetPlatformValue = this.getTargetPlatform(project)

        def addFlutterDeps = { variant ->
            String flutterBuildMode = buildModeFor(variant.buildType)

            if (flutterBuildMode == 'debug' && project.tasks.findByName('${flutterBuildPrefix}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 = []
            def targetPlatforms = []

            if (targetPlatformValue == 'android-arm-all') {
                if (flutterBuildMode == 'release') {
                    targetPlatforms.addAll(allArmPlatforms)
                } else {
                    targetPlatforms.add('android-arm')
                }
            } else {
                targetPlatforms.add(targetPlatformValue)
            }

            targetPlatforms.each { currentTargetPlatformValue ->
                String abiValue = allTargetPlatforms[currentTargetPlatformValue]
                FlutterTask compileTask = project.tasks.create(name: "${flutterBuildPrefix}${variant.name.capitalize()}${currentTargetPlatformValue}:compile", 
                    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
                    buildSharedLibrary buildSharedLibraryValue
                    targetPlatform currentTargetPlatformValue
                    sourceDir project.file(project.flutter.source)
                    intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/${currentTargetPlatformValue}")
                    extraFrontEndOptions extraFrontEndOptionsValue
                    extraGenSnapshotOptions extraGenSnapshotOptionsValue
                }
                flutterTasks.add(compileTask)
            }

            def libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/libs.jar")
            Task packFlutterSnapshotsAndLibsTask = project.tasks.create(name: ":flutter:package:packLibs${variant.name.capitalize()}", type: Jar) {
                destinationDir libJar.parentFile
                archiveName libJar.name
                targetPlatforms.each { targetPlatform ->
                    // Include `libflutter.so` for each abi.
                    // TODO(blasten): The libs should be outside `flutter.jar` when the artifacts are downloaded.
                    from(project.zipTree("${flutterRoot}/bin/cache/artifacts/engine/${targetPlatform}-release/flutter.jar")) {
                        include 'lib/**'
                    }
                }

                dependsOn flutterTasks
                // Add the snapshots and rename them as `lib/{abi}/*.so`.
                flutterTasks.each { flutterTask -> 
                    from(flutterTask.intermediateDir) {
                        include 'vm_snapshot_data'
                        include 'vm_snapshot_instr'
                        include 'isolate_snapshot_data'
                        include 'isolate_snapshot_instr'
                        rename {  String filename ->
                            return "lib/${flutterTask.abi}/lib_${filename}.so"
                        }
                    }
                }
            }

            // Include the snapshots and libflutter.so in `lib/`.
            if (flutterBuildMode == 'release' && targetPlatformValue == 'android-arm-all') {
                project.dependencies {
                    String configuration;
                    if (project.getConfigurations().findByName("api")) {
                        configuration = buildType.name + "Api";
                    } else {
                        configuration = buildType.name + "Compile";
                    }
                    add(configuration, 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()}"
                    into variant.mergeAssets.outputDir
                }
                flutterTasks.each { flutterTask -> 
                    with flutterTask.assets
                    // Include the snapshots in the assets directory.
                    if (flutterBuildMode != 'release' || targetPlatformValue != 'android-arm-all') {
                        with flutterTask.snapshots
                    }
                }
            }
            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
    Boolean buildSharedLibrary
    @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 "--target", targetPath
                args "--output-dir", "${intermediateDir}"
                if (trackWidgetCreation) {
                    args "--track-widget-creation"
                }
                if (extraFrontEndOptions != null) {
                    args "--extra-front-end-options", "${extraFrontEndOptions}"
                }
                if (extraGenSnapshotOptions != null) {
                    args "--extra-gen-snapshot-options", "${extraGenSnapshotOptions}"
                }
                if (buildSharedLibrary) {
                    args "--build-shared-library"
                }
                if (targetPlatform == null) {
                    args "--target-platform", "android-arm"
                } else {
                    args "--target-platform", "${targetPlatform}"
                }
                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 "--suppress-analytics"
            args "--target", targetPath
            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 (targetPlatform != null) {
                args "--target-platform", "${targetPlatform}"
            }
            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" || buildMode == "dynamicProfile") {
                args "--profile"
            }
            if (buildMode == "release" || buildMode == "dynamicRelease") {
                args "--release"
            }
            if (buildMode == "dynamicProfile" || buildMode == "dynamicRelease") {
                args "--dynamic"
            }
        }
    }
}

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') {
                if (buildSharedLibrary) {
                    include "app.so"
                } else {
                    include "vm_snapshot_data"
                    include "vm_snapshot_instr"
                    include "isolate_snapshot_data"
                    include "isolate_snapshot_instr"
                }
            }
        }
    }

    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.flutterBuildPrefix)) {
                result.rethrowFailure()
            }
        }
    }
}
