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 {
        jcenter()
        maven {
            url 'https://dl.google.com/dl/android/maven2'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
    }
}

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

    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("flutterBuildX86Jar", 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 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)
                    releaseCompileOnly project.files(releaseFlutterJar)
                } else {
                    debugProvided project.files(debugFlutterJar)
                    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"
    }

    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('precompile')) {
            compilationTraceFilePathValue = project.property('precompile')
        }
        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('flutterBuildX86Jar')) {
                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: "flutterBuild${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
                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
            }

            Task copyFlutterAssetsTask = project.tasks.create(name: "copyFlutterAssets${variant.name.capitalize()}", type: Copy) {
                dependsOn flutterTask
                dependsOn variant.mergeAssets
                dependsOn "clean${variant.mergeAssets.name.capitalize()}"
                into variant.mergeAssets.outputDir
                with flutterTask.assets
            }
            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
    @Optional @Input
    Boolean trackWidgetCreation
    @Optional @Input
    String compilationTraceFilePath
    @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 "--precompile", compilationTraceFilePath
            }
            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 != 'debug' || compilationTraceFilePath) {
                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> <space>
                String depText = dependenciesFile.text
                return project.files(depText.split(': ')[1].split())
            } 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()
    }
}
