// Adapted from https://raw.githubusercontent.com/facebook/react-native/master/local-cli/generator-android/templates/src/app/react.gradle

def config = project.hasProperty("react") ? project.react : [];
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"

def elvisFile(thing) {
    return thing ? file(thing) : null;
}

void runBefore(String dependentTaskName, Task task) {
    Task dependentTask = tasks.findByPath(dependentTaskName);
    if (dependentTask != null) {
        dependentTask.dependsOn task
    }
}

gradle.projectsEvaluated {
    def buildTypes = android.buildTypes.collect { type -> type.name }
    android.buildTypes.each {
        it.resValue 'string', "CODE_PUSH_APK_BUILD_TIME", Long.toString(System.currentTimeMillis())
    }
    def productFlavors = android.productFlavors.collect { flavor -> flavor.name }
    if (!productFlavors) productFlavors.add('')
    def nodeModulesPath;
    if (project.hasProperty('nodeModulesPath')) {
        nodeModulesPath = project.nodeModulesPath
    } else {
        nodeModulesPath = "../../node_modules";
    }

    productFlavors.each { productFlavorName ->
        buildTypes.each { buildTypeName ->
            def targetName = "${productFlavorName.capitalize()}${buildTypeName.capitalize()}"
            def targetPath = productFlavorName ?
                    "${productFlavorName}/${buildTypeName}" :
                    "${buildTypeName}"

            def jsBundleDirConfigName = "jsBundleDir${targetName}"
            def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
                    file("$buildDir/intermediates/assets/${targetPath}")

            def resourcesDirConfigName = "jsBundleDir${targetName}"
            def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
                    file("$buildDir/intermediates/res/merged/${targetPath}")

            // In case version of 'Android Plugin for Gradle'' is lower than 1.3.0 
            // '$buildDir' has slightly different structure - 'merged' folder
            // does not exists so '${targetPath}' folder contains directly in 'res' folder.
            if (!resourcesDir.exists() && file("$buildDir/intermediates/res/${targetPath}").exists()) {
                resourcesDir = file("$buildDir/intermediates/res/${targetPath}")
            }
            
            def jsBundleFile = file("$jsBundleDir/$bundleAssetName")

            // Make this task run right before the bundle task
            def recordFilesBeforeBundleCommand = tasks.create(
                    name: "recordFilesBeforeBundleCommand${targetName}",
                    type: Exec) {
                commandLine "node", "${nodeModulesPath}/react-native-code-push/scripts/recordFilesBeforeBundleCommand.js", resourcesDir
            }

            recordFilesBeforeBundleCommand.dependsOn("merge${targetName}Resources")
            recordFilesBeforeBundleCommand.dependsOn("merge${targetName}Assets")
            runBefore("bundle${targetName}JsAndAssets", recordFilesBeforeBundleCommand)

            // Make this task run right after the bundle task
            def generateBundledResourcesHash = tasks.create(
                    name: "generateBundledResourcesHash${targetName}",
                    type: Exec) {
                commandLine "node", "${nodeModulesPath}/react-native-code-push/scripts/generateBundledResourcesHash.js", resourcesDir, "$jsBundleDir/$bundleAssetName", jsBundleDir
            }

            generateBundledResourcesHash.dependsOn("bundle${targetName}JsAndAssets")
            runBefore("processArmeabi-v7a${targetName}Resources", generateBundledResourcesHash)
            runBefore("processX86${targetName}Resources", generateBundledResourcesHash)
            runBefore("processUniversal${targetName}Resources", generateBundledResourcesHash)
            runBefore("process${targetName}Resources", generateBundledResourcesHash)
        }
    }
}
