package com.novoda.notils.logger.simple;

/**
 * Wrapper around Android Log that will print
 * <p/>
 * 'TAG [Thread Name][Class name][Method name:line number] message'
 */
public final class Log {

    /**
     * Flag to enable or disable logs
     * Recommended you set this to BuildConfig.DEBUG in your class that extends Application
     */
    public static boolean SHOW_LOGS = false;
    /**
     * Log tag to use - Default is 'NoTils'
     */
    public static String TAG = "NoTils";
    /**
     * How deep to log stack traces - Default is 5
     */
    public static int STACK_DEPTH = 5;

    private static final int DOT_CLASS = 5;

    /**
     * Separator for the concatenation of the vaargs
     */
    private static String separator = " ";

    private Log() {
    }

    public static void setSeparator(String separator) {
        Log.separator = separator;
    }

    public static void v(Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.v(TAG, getDetailedLog(formatString(msg)));
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    public static void i(Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.i(TAG, getDetailedLog(formatString(msg)));
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    public static void d(Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.d(TAG, getDetailedLog(formatString(msg)));
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    public static void w(Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.w(TAG, getDetailedLog(formatString(msg)));
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    public static void e(Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.e(TAG, getDetailedLog(formatString(msg)));
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    @Deprecated
    /**
     * @deprecated use (Throwable t, Object... msg) 
     */
    public static void w(String msg, Throwable t) {
        w(t, msg);
    }

    public static void w(Throwable t, Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.w(TAG, getDetailedLog(formatString(msg)), t);
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    @Deprecated
    /**
     * @deprecated use (Throwable t, Object... msg)
     */
    public static void d(String msg, Throwable t) {
        d(t, msg);
    }

    public static void d(Throwable t, Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.d(TAG, getDetailedLog(formatString(msg)), t);
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    @Deprecated
    /**
     * @deprecated use (Throwable t, Object... msg) 
     */
    public static void e(String msg, Throwable t) {
        e(t, msg);
    }

    public static void e(Throwable t, Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.e(TAG, getDetailedLog(formatString(msg)), t);
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    @Deprecated
    /**
     * @deprecated use (Throwable t, Object... msg)
     */
    public static void wtf(String msg, Throwable t) {
        wtf(t, msg);
    }

    public static void wtf(Throwable t, Object... msg) {
        try {
            if (SHOW_LOGS) {
                Log.wtf(TAG, getDetailedLog(formatString(msg)), t);
            }
        } catch (RuntimeException ignore) {
            logError(ignore);
        }
    }

    private static String getDetailedLog(String msg) {
        return getDetailedLog(msg, STACK_DEPTH);
    }

    private static String getDetailedLog(String msg, int depth) {
        if (!SHOW_LOGS) {
            return msg;
        }
        Thread current = Thread.currentThread();
        final StackTraceElement trace = current.getStackTrace()[depth];
        final String filename = trace.getFileName();
        return "[" + current.getName() + "][" + filename.substring(0, filename.length() - DOT_CLASS) + "."
                + trace.getMethodName() + ":" + trace.getLineNumber() + "] " + msg;
    }

    private static void logError(Throwable ignore) {
        Log.e(TAG, "Error", ignore);
    }

    private static String formatString(Object... msg) {
        StringBuilder stringBuilder = new StringBuilder();
        for (Object o : msg) {
            stringBuilder.append(String.valueOf(o)).append(separator);
        }
        return stringBuilder.toString();
    }

    /**
     * Toggle if logs should be output or not. Recommended to bind against BuildConfig.DEBUG
     * @param showLogs <code>true</code> for showing logs, <code>false</code> to deactivate
     */
    public static void setShowLogs(boolean showLogs) {
        Log.SHOW_LOGS = showLogs;
    }
}

@@ -970,24 +970,37 @@
             
+android.util.
 Log.v(TAG, g
@@ -1026,32 +1026,32 @@
 tString(msg)));%0A
-
             %7D%0A  
@@ -1236,24 +1236,37 @@
             
+android.util.
 Log.i(TAG, g
@@ -1498,32 +1498,45 @@
                 
+android.util.
 Log.d(TAG, getDe
@@ -1764,32 +1764,45 @@
                 
+android.util.
 Log.w(TAG, getDe
@@ -2030,32 +2030,45 @@
                 
+android.util.
 Log.e(TAG, getDe
@@ -2352,17 +2352,16 @@
     w(t,
- 
 msg);%0A  
@@ -2475,24 +2475,37 @@
             
+android.util.
 Log.w(TAG, g
@@ -2919,24 +2919,37 @@
             
+android.util.
 Log.d(TAG, g
@@ -3360,32 +3360,45 @@
                 
+android.util.
 Log.e(TAG, getDe
@@ -3814,24 +3814,37 @@
             
+android.util.
 Log.wtf(TAG,
@@ -4646,32 +4646,32 @@
 e ignore) %7B%0A
-
         
 Log.e(TAG, %22
@@ -4654,24 +4654,37 @@
 ) %7B%0A        
+android.util.
 Log.e(TAG, %22

Fix Log class usage "auto-fixed" by Android Studio