import org.apache.tools.ant.taskdefs.condition.Os

def config = project.hasProperty("react") ? project.react : [];

def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
def entryFile = config.entryFile ?: "index.android.js"

// because elvis operator
def elvisFile(thing) {
    return thing ? file(thing) : null;
}

def reactRoot = elvisFile(config.root) ?: file("../../")
def jsBundleDirDebug = elvisFile(config.jsBundleDirDebug) ?:
        file("$buildDir/intermediates/assets/debug")
def jsBundleDirRelease = elvisFile(config.jsBundleDirRelease) ?:
        file("$buildDir/intermediates/assets/release")
def resourcesDirDebug = elvisFile(config.resourcesDirDebug) ?:
        file("$buildDir/intermediates/res/merged/debug")
def resourcesDirRelease = elvisFile(config.resourcesDirRelease) ?:
        file("$buildDir/intermediates/res/merged/release")
def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]

def jsBundleFileDebug = file("$jsBundleDirDebug/$bundleAssetName")
def jsBundleFileRelease = file("$jsBundleDirRelease/$bundleAssetName")

task bundleDebugJsAndAssets(type: Exec) {
    // create dirs if they are not there (e.g. the "clean" task just ran)
    doFirst {
        jsBundleDirDebug.mkdirs()
        resourcesDirDebug.mkdirs()
    }

    // set up inputs and outputs so gradle can cache the result
    inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
    outputs.dir jsBundleDirDebug
    outputs.dir resourcesDirDebug

    // set up the call to the react-native cli
    workingDir reactRoot
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        commandLine "cmd", "/c", "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file",
            entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug
    } else {
        commandLine "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file",
            entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug
    }

    enabled config.bundleInDebug ?: false
}

task bundleReleaseJsAndAssets(type: Exec) {
    // create dirs if they are not there (e.g. the "clean" task just ran)
    doFirst {
        jsBundleDirRelease.mkdirs()
        resourcesDirRelease.mkdirs()
    }

    // set up inputs and outputs so gradle can cache the result
    inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
    outputs.dir jsBundleDirRelease
    outputs.dir resourcesDirRelease

    // set up the call to the react-native cli
    workingDir reactRoot
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        commandLine "cmd","/c", "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
            entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease
    } else {
        commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
            entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease
    }

    enabled config.bundleInRelease ?: true
}

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

gradle.projectsEvaluated {

    // hook bundleDebugJsAndAssets into the android build process

    bundleDebugJsAndAssets.dependsOn mergeDebugResources
    bundleDebugJsAndAssets.dependsOn mergeDebugAssets

    runBefore('processArmeabi-v7aDebugResources', bundleDebugJsAndAssets)
    runBefore('processX86DebugResources', bundleDebugJsAndAssets)
    runBefore('processUniversalDebugResources', bundleDebugJsAndAssets)
    runBefore('processDebugResources', bundleDebugJsAndAssets)

    // hook bundleReleaseJsAndAssets into the android build process

    bundleReleaseJsAndAssets.dependsOn mergeReleaseResources
    bundleReleaseJsAndAssets.dependsOn mergeReleaseAssets

    runBefore('processArmeabi-v7aReleaseResources', bundleReleaseJsAndAssets)
    runBefore('processX86ReleaseResources', bundleReleaseJsAndAssets)
    runBefore('processUniversalReleaseResources', bundleReleaseJsAndAssets)
    runBefore('processReleaseResources', bundleReleaseJsAndAssets)

}
