package alexander.martinz.libs.execution.binaries;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;

import alexander.martinz.libs.execution.ShellHelper;
import alexander.martinz.libs.execution.ShellLogger;

public class BusyBox {
    private static final String TAG = BusyBox.class.getSimpleName();

    // my favorite
    private static final String PLAY_STORE_BUSYBOX = "https://play.google.com/store/apps/details?id=stericson.busybox";

    private static final String[] PATH_BUSYBOX = new String[]{
            "/system/bin/busybox", "/system/xbin/busybox"
    };

    private static Boolean sHasBusybox = null;

    public static boolean isAvailable() {
        return isAvailable(false);
    }

    public static boolean isAvailable(boolean forceCheck) {
        if (!forceCheck && sHasBusybox != null) {
            return sHasBusybox;
        }

        final String busyboxPath = getBusyboxPath();
        if (!TextUtils.isEmpty(busyboxPath)) {
            if (ShellLogger.DEBUG) {
                Log.d(TAG, String.format("Found busybox path: %s", busyboxPath));
            }
            sHasBusybox = true;
            return true;
        }
        if (ShellLogger.DEBUG) {
            Log.d(TAG, "no busybox binary found, trying with hit and miss");
        }

        final String busyboxLocation = ShellHelper.findBinary("busybox");
        if (!TextUtils.isEmpty(busyboxLocation)) {
            if (ShellLogger.DEBUG) {
                Log.d(TAG, String.format("Found busybox path: %s", busyboxLocation));
            }
            sHasBusybox = true;
            return true;
        }
        return sHasBusybox;
    }

    /**
     * @return The path of the busybox binary or null if none found
     */
    @Nullable public static String getBusyboxPath() {
        for (final String path : PATH_BUSYBOX) {
            if (new File(path).exists()) {
                return path;
            }
        }
        return null;
    }

    @Nullable public static String callBusyBoxApplet(@NonNull Context context, @NonNull String applet, @Nullable String args) {
        final File fileDir = context.getFilesDir();
        if (!fileDir.exists()) {
            if (ShellLogger.DEBUG) {
                Log.e(TAG, "Files folder does not exist!");
            }
            return null;
        }

        final File busybox = new File(fileDir, "busybox");
        if (!busybox.exists()) {
            Log.e(TAG, "busybox binary does not exist!");
            return null;
        }

        String cmd = String.format("%s %s", busybox.getAbsolutePath(), applet);
        if (TextUtils.isEmpty(args)) {
            Log.e(TAG, String.format("No args specified, returning -> %s", cmd));
            return cmd;
        }

        cmd = String.format("%s %s", cmd, args);
        if (ShellLogger.DEBUG) {
            Log.v(TAG, String.format("Calling applet with args -> %s", cmd));
        }
        return cmd;
    }

    public static void offerBusyBox(@NonNull Context context) {
        final Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(PLAY_STORE_BUSYBOX));
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            context.startActivity(i);
        } catch (Exception ignored) { }
    }
}

@@ -813,16 +813,63 @@
  = null;
+%0A    private static String sBusyBoxPath = null;
 %0A%0A    pu
@@ -1356,32 +1356,72 @@
 Busybox = true;%0A
+            sBusyBoxPath = busyboxPath;%0A
             retu
@@ -1870,57 +1870,313 @@
     
-return true;%0A        %7D%0A        return sHasBusybox
+sBusyBoxPath = busyboxLocation.endsWith(%22/%22)%0A                    ? String.format(%22%25s%25s%22, busyboxLocation, %22busybox%22)%0A                    : String.format(%22%25s/%25s%22, busyboxLocation, %22busybox%22);%0A            return true;%0A        %7D%0A%0A        sHasBusybox = false;%0A        sBusyBoxPath = null;%0A        return false
 ;%0A  
@@ -2545,32 +2545,986 @@
 Applet(@NonNull 
+String applet) %7B%0A        return callBusyBoxApplet(applet, null);%0A    %7D%0A%0A    @Nullable public static String callBusyBoxApplet(@NonNull String applet, @Nullable String args) %7B%0A        if (!isAvailable() %7C%7C TextUtils.isEmpty(sBusyBoxPath)) %7B%0A            return null;%0A        %7D%0A%0A        String cmd = String.format(%22%25s %25s%22, sBusyBoxPath, applet);%0A        if (TextUtils.isEmpty(args)) %7B%0A            Log.v(TAG, String.format(%22No args specified, returning -%3E %25s%22, cmd));%0A            return cmd;%0A        %7D%0A%0A        cmd = String.format(%22%25s %25s%22, cmd, args);%0A        if (ShellLogger.DEBUG) %7B%0A            Log.v(TAG, String.format(%22Calling applet with args -%3E %25s%22, cmd));%0A        %7D%0A        return cmd;%0A    %7D%0A%0A    @Nullable public static String callBusyBoxAppletInternal(@NonNull Context context, @NonNull String applet) %7B%0A        return callBusyBoxAppletInternal(context, applet, null);%0A    %7D%0A%0A    @Nullable%0A    public static String callBusyBoxAppletInternal(@NonNull 
 Context context,
@@ -4122,25 +4122,25 @@
         Log.
-e
+v
 (TAG, String

add method to call external busybox binary