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.0.1'
    }
}

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 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(project.rootProject.file("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 a 'profile' build type
        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 (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("implementation")) {
                    implementation 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()
            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")
            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>Implementation configurations, including custom ones
            // added after applying the Flutter plugin.
            project.android.buildTypes.each { addFlutterJarImplementationDependency(project, it) }
            project.android.buildTypes.whenObjectAdded { addFlutterJarImplementationDependency(project, it) }
        }

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

        File pluginsFile = new File(project.rootProject.projectDir.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 implementation dependencies to the specified buildType.
     *
     * Note: The BuildType DSL type is not public, and is therefore omitted from the signature.
     */
    private void addFlutterJarImplementationDependency(Project project, buildType) {
        project.dependencies {
            String configuration;
            if (project.getConfigurations().findByName("implementation")) {
                configuration = buildType.name + "Implementation";
            } else {
                configuration = buildType.name + "Compile";
            }
            add(configuration, project.files {
                String buildMode = buildModeFor(buildType)
                if (buildMode == "debug") {
                    [flutterX86Jar, debugFlutterJar]
                } else if (buildMode == "profile") {
                    profileFlutterJar
                } 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", or "release" (fall-back).
     */
    private static String buildModeFor(buildType) {
        if (buildType.name == "profile") {
            return "profile"
        } 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 previewDart2Value = false
        if (project.hasProperty('preview-dart-2')) {
            previewDart2Value = project.property('preview-dart-2').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 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 preferSharedLibraryValue = false
        if (project.hasProperty('prefer-shared-library')) {
            preferSharedLibraryValue = project.property('prefer-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
                previewDart2 previewDart2Value
                fileSystemRoots fileSystemRootsValue
                fileSystemScheme fileSystemSchemeValue
                trackWidgetCreation trackWidgetCreationValue
                preferSharedLibrary preferSharedLibraryValue
                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 previewDart2
    @Optional @Input
    String[] fileSystemRoots
    @Optional @Input
    String fileSystemScheme
    @Optional @Input
    Boolean trackWidgetCreation
    @Optional @Input
    Boolean preferSharedLibrary
    @Optional @Input
    String targetPlatform
    File sourceDir
    File intermediateDir
    @Optional @Input
    String extraFrontEndOptions
    @Optional @Input
    String extraGenSnapshotOptions

    @OutputFile
    File getDependenciesFile() {
        if (buildMode != 'debug') {
            return project.file("${intermediateDir}/snapshot.d")
        }
        return project.file("${intermediateDir}/snapshot_blob.bin.d")
    }

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

        intermediateDir.mkdirs()

        if (buildMode != "debug") {
            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 (previewDart2) {
                    args "--preview-dart-2"
                } else {
                    args "--no-preview-dart-2"
                }
                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 (preferSharedLibrary) {
                    args "--prefer-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 (previewDart2) {
                args "--preview-dart-2"
            } else {
                args "--no-preview-dart-2"
            }
            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 (buildMode != "debug") {
                args "--precompiled"
            } else {
                args "--depfile", "${intermediateDir}/snapshot_blob.bin.d"
                if (!previewDart2) {
                    args "--snapshot", "${intermediateDir}/snapshot_blob.bin"
                }
            }
            args "--asset-dir", "${intermediateDir}/flutter_assets"
        }
    }
}

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') {
                if (preferSharedLibrary) {
                    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 null
    }

    @InputFiles
    FileCollection getSourceFiles() {
        File dependenciesFile = getDependenciesFile()
        FileCollection sources = readDependencies(dependenciesFile)
        if (sources != null) {
            // We have a dependencies file. Add a dependency on gen_snapshot as well, since the
            // snapshots have to be rebuilt if it changes.
            FileCollection snapshotter = readDependencies(project.file("${intermediateDir}/gen_snapshot.d"))
            if (snapshotter != null) {
                sources = sources.plus(snapshotter)
            }
            if (previewDart2) {
                FileCollection frontendServer = readDependencies(project.file("${intermediateDir}/frontend_server.d"))
                if (frontendServer != null) {
                    sources = sources.plus(frontendServer)
                }
            }
            if (localEngineSrcPath != null) {
                sources = sources.plus(project.files("$localEngineSrcPath/$localEngine"))
            }
            // Finally, add a dependency on pubspec.yaml as well.
            return sources.plus(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()
    }
}
