package invalid.lena.rsend

import android.content.Context
import java.io.File
import java.util.concurrent.TimeUnit

// Native locates and runs the executables shipped inside the APK as lib*.so.
// Android only allows exec of native code from the app's native library dir,
// so the rsync and rsh binaries are packaged there and run from there.
object Native {

    fun rsync(ctx: Context): File = File(ctx.applicationInfo.nativeLibraryDir, "libxrsync.so")

    fun rsh(ctx: Context): File = File(ctx.applicationInfo.nativeLibraryDir, "libxrsh.so")

    data class Result(val code: Int, val output: String)

    // Blocking; call off the main thread. stderr is merged into stdout.
    fun run(bin: File, args: List<String>, env: Map<String, String> = emptyMap()): Result {
        val pb = ProcessBuilder(listOf(bin.absolutePath) + args).redirectErrorStream(true)
        pb.environment().putAll(env)
        val p = pb.start()
        if (!p.waitFor(45, TimeUnit.SECONDS)) {
            p.destroyForcibly()
            p.waitFor()
            throw IllegalStateException("${bin.name} timed out")
        }
        val out = p.inputStream.bufferedReader().use { it.readText() }
        val code = p.exitValue()
        return Result(code, out)
    }
}
