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 File flutterRoot
    private File flutterExecutable
    private String localEngine
    private String localEngineSrcPath
    private Properties localProperties

    private File flutterJar
    private File flutterX86Jar
    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"

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

    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) {
        // 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')
            }
            flutterJar = Paths.get(engineOut.absolutePath, "flutter.jar").toFile()
            if (!flutterJar.isFile()) {
                throw new GradleException('Local engine build does not contain flutter.jar')
            }

            localEngine = engineOut.name
            localEngineSrcPath = engineOut.parentFile.parent

            project.dependencies {
                if (project.getConfigurations().findByName("api")) {
                    api project.files(flutterJar)
                } else {
                    compile project.files(flutterJar)
                }
            }
        } else {
            Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
            String targetArch = 'arm'
            if (project.hasProperty('target-platform') &&
                project.property('target-platform') == 'android-arm64') {
              targetArch = 'arm64'
            }
            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.
            flutterX86Jar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/flutter-x86.jar")
            Task flutterX86JarTask = 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, flutterX86JarTask) }
            project.android.buildTypes.whenObjectAdded { addFlutterJarApiDependency(project, it, flutterX86JarTask) }
        }

        project.extensions.create("flutter", FlutterExtension)
        project.afterEvaluate this.&addFlutterTask

        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 flutterX86JarTask) {
        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)
                if (buildMode == "debug") {
                    [flutterX86JarTask, debugFlutterJar]
                } else if (buildMode == "profile") {
                    profileFlutterJar
                } else if (buildMode == "dynamicProfile") {
                    dynamicProfileFlutterJar
                } else if (buildMode == "dynamicRelease") {
                    dynamicReleaseFlutterJar
                } else {
                    releaseFlutterJar
                }
            })
        }
    }

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

    /**
     * Returns a Flutter Jar file path suitable for the specified Android buildMode.
     */
    private File flutterJarFor(buildMode) {
        if (buildMode == "profile") {
            return profileFlutterJar
        } else if (buildMode == "dynamicProfile") {
            return dynamicProfileFlutterJar
        } else if (buildMode == "dynamicRelease") {
            return dynamicReleaseFlutterJar
        } else if (buildMode == "debug") {
            return debugFlutterJar
        }
        return releaseFlutterJar
    }

    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 = false
        if (project.hasProperty('build-shared-library')) {
            buildSharedLibraryValue = project.property('build-shared-library').toBoolean()
        }
        String targetPlatformValue = null
        if (project.hasProperty('target-platform')) {
            targetPlatformValue = project.property('target-platform')
        }

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

            FlutterTask flutterTask = project.tasks.create(name: "${flutterBuildPrefix}${variant.name.capitalize()}", type: FlutterTask) {
                flutterRoot this.flutterRoot
                flutterExecutable this.flutterExecutable
                buildMode flutterBuildMode
                localEngine this.localEngine
                localEngineSrcPath this.localEngineSrcPath
                targetPath target
                verbose verboseValue
                fileSystemRoots fileSystemRootsValue
                fileSystemScheme fileSystemSchemeValue
                trackWidgetCreation trackWidgetCreationValue
                compilationTraceFilePath compilationTraceFilePathValue
                createPatch createPatchValue
                buildNumber buildNumberValue
                baselineDir baselineDirValue
                buildSharedLibrary buildSharedLibraryValue
                targetPlatform targetPlatformValue
                sourceDir project.file(project.flutter.source)
                intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}")
                extraFrontEndOptions extraFrontEndOptionsValue
                extraGenSnapshotOptions extraGenSnapshotOptionsValue
            }

            // 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 flutterTask
                if (packageAssets && cleanPackageAssets) {
                    dependsOn packageAssets
                    dependsOn cleanPackageAssets
                    into packageAssets.outputDir

                    File chosenFlutterJar = flutterJarFor(flutterBuildMode)
                    Task copySharedFlutterAssetsTask = project.tasks.create(name: "copySharedFlutterAssets${variant.name.capitalize()}", type: Copy) {
                        from(project.zipTree(chosenFlutterJar))
                        include 'assets/flutter_shared/*'
                        into "src/${variant.name}"
                    }
                    dependsOn copySharedFlutterAssetsTask
                } else {
                    dependsOn variant.mergeAssets
                    dependsOn "clean${variant.mergeAssets.name.capitalize()}"
                    into variant.mergeAssets.outputDir
                }
                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 {
                variant.outputs[0].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
    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 "--target-platform", "android-arm"
                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", "${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

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