// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import static groovy.io.FileType.FILES

import com.android.builder.model.AndroidProject
import com.android.build.OutputFile
import java.nio.file.Path
import java.nio.file.Paths
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.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.&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 (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]
                })
            }
        }
    }

    /**
     * Returns the directory where the plugins are built.
     */
    private File getPluginBuildDir(Project project) {
        // 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
    }

    private Properties getPluginList(Project project) {
        File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins')
        return readPropertiesIfExist(pluginsFile)
    }

    private void addPluginTasks(Project project) {
        Properties plugins = getPluginList(project)
        project.android.buildTypes.each { buildType ->
            plugins.each { name, path ->
                String buildModeValue = buildType.debuggable ? "debug" : "release"
                List<String> taskNameParts = ["build", "plugin", buildModeValue]
                taskNameParts.addAll(name.split("_"))
                String taskName = toCammelCase(taskNameParts)
                // Build types can be extended. For example, a build type can extend the `debug` mode.
                // In such cases, prevent creating the same task.
                if (project.tasks.findByName(taskName) == null) {
                    project.tasks.create(name: taskName, type: FlutterPluginTask) {
                        flutterExecutable this.flutterExecutable
                        buildMode buildModeValue
                        verbose isVerbose(project)
                        pluginDir project.file(path)
                        sourceDir project.file(project.flutter.source)
                        intermediateDir getPluginBuildDir(project)
                    }
                }
            }
        }
    }

    private void buildPlugins(Project project, Set buildTypes) {
        List<Project> projects = [project]
        // Module projects set the `hostProjects` extra property in `include_flutter.groovy`.
        // This is required to set the local repository in each host app project.
        if (project.ext.has("hostProjects")) {
            projects.addAll(project.ext.get("hostProjects"))
        }
        projects.each { hostProject ->
            hostProject.repositories {
                maven {
                    url "${getPluginBuildDir(project)}/outputs/repo"
                }
            }
        }
        buildTypes.each { buildType ->
            project.tasks.withType(FlutterPluginTask).all { pluginTask ->
                String buildMode = buildType.debuggable ? "debug" : "release"
                if (pluginTask.buildMode != buildMode) {
                    return
                }
                pluginTask.execute()
                pluginTask.intermediateDir.eachFileRecurse(FILES) { file ->
                    if (file.name != "maven-metadata.xml") {
                        return
                    }
                    def mavenMetadata = new XmlParser().parse(file)
                    String groupId = mavenMetadata.groupId.text()
                    String artifactId = mavenMetadata.artifactId.text()

                    if (!artifactId.endsWith(buildMode)) {
                        return
                    }
                    // Add the plugin dependency based on the Maven metadata.
                    addApiDependencies(project, buildType.name, "$groupId:$artifactId:+@aar", {
                        transitive = true
                    })
                }
            }
        }
    }

    /**
     * Returns a set with the build type names that apply to the given list of tasks
     * required to configure the plugin dependencies.
     */
    private Set getBuildTypesForTasks(Project project, List<String> tasksToExecute) {
        Set buildTypes = []
        tasksToExecute.each { task ->
            project.android.buildTypes.each { buildType ->
                if (task == "androidDependencies" || task.endsWith("dependencies")) {
                    // The tasks to query the dependencies includes all the build types.
                    buildTypes.add(buildType)
                } else if (task.endsWith("assemble")) {
                    // The `assemble` task includes all the build types.
                    buildTypes.add(buildType)
                } else if (task.endsWith(buildType.name.capitalize())) {
                    buildTypes.add(buildType)
                }
            }
        }
        return buildTypes
    }

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

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

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

    private static Boolean buildPluginAsAar() {
        return System.getProperty('build-plugins-as-aars') == 'true'
    }

    /**
     * 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;
    }

    private void addFlutterJarCompileOnlyDependency(Project project, String variantName, FileCollection files) {
        if (project.state.failure) {
            return
        }
        String configuration;
        if (project.getConfigurations().findByName("compileOnly")) {
            configuration = "${variantName}CompileOnly";
        } else {
            configuration = "${variantName}Provided";
        }
        project.dependencies.add(configuration, files)
    }

    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 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 compileTasks = targetPlatforms.collect { targetArch ->
                String abiValue = PLATFORM_ARCH_MAP[targetArch]
                String taskName = toCammelCase(["compile", FLUTTER_BUILD_PREFIX, variant.name, targetArch.replace('android-', '')])
                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 isVerbose(project)
                    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
                }
            }

            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 compileTasks
                // Add the ELF library.
                compileTasks.each { compileTask ->
                    from(compileTask.intermediateDir) {
                        include '*.so'
                        rename { String filename ->
                            return "lib/${compileTask.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 compileTasks
                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
                }
                compileTasks.each { flutterTask ->
                    with flutterTask.assets
                }
            }
            variant.outputs.first().processResources.dependsOn(copyFlutterAssetsTask)
        }
        if (project.android.hasProperty("applicationVariants")) {
            project.android.applicationVariants.all addFlutterDeps
        } else {
            project.android.libraryVariants.all addFlutterDeps
        }

        if (buildPluginAsAar()) {
            addPluginTasks(project)

            List<String> tasksToExecute = project.gradle.startParameter.taskNames
            Set buildTypes = getBuildTypesForTasks(project, tasksToExecute)
            if (tasksToExecute.contains("clean")) {
                // Because the plugins are built during configuration, the task "clean"
                // cannot run in conjunction with an assembly task.
                if (!buildTypes.empty) {
                    throw new GradleException("Can't run the clean task along with other assemble tasks")
                }
            }
            // Build plugins when a task "assembly*" will be called later.
            if (!buildTypes.empty) {
                // Build the plugin during configuration.
                // This is required when Jetifier is enabled, otherwise the implementation dependency
                // cannot be added.
                buildPlugins(project, buildTypes)
            }
        } else {
            getPluginList(project).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.android.buildTypes.each {
                            def buildMode = buildModeFor(it)
                            addFlutterJarCompileOnlyDependency(pluginProject, it.name, project.files( flutterJar ?: baseJar[buildMode] ))
                        }
                        pluginProject.android.buildTypes.whenObjectAdded {
                            def buildMode = buildModeFor(it)
                            addFlutterJarCompileOnlyDependency(pluginProject, it.name, project.files( flutterJar ?: baseJar[buildMode] ))
                        }
                    }
                } else {
                    project.logger.error("Plugin project :$name not found. Please update settings.gradle.")
                }
            }
        }
    }
}

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

class FlutterPluginTask extends DefaultTask {
    File flutterExecutable
    @Optional @Input
    Boolean verbose
    @Input
    String buildMode
    @Input
    File pluginDir
    @Input
    File intermediateDir
    File sourceDir

    @InputFiles
    FileCollection getSourceFiles() {
        return project.fileTree(
            dir: sourceDir,
            exclude: ["android", "ios"],
            include: ["pubspec.yaml"]
        )
    }

    @OutputDirectory
    File getOutputDirectory() {
        return intermediateDir
    }

    @TaskAction
    void build() {
        intermediateDir.mkdirs()
        project.exec {
            executable flutterExecutable.absolutePath
            workingDir pluginDir
            args "build", "aar"
            args "--quiet"
            args "--suppress-analytics"
            args "--output-dir", "${intermediateDir}"
            switch (buildMode) {
                case 'release':
                    args "--release"
                    break
                case 'debug':
                    args "--debug"
                    break
                default:
                    assert false
            }
            if (verbose) {
                args "--verbose"
            }
        }
    }
}

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