package jp.gr.java_conf.shiseissi.commonlib;

import java.lang.ref.SoftReference;

/**
 *
 * @author shisei
 */
public abstract class Log {
    private static final String MSG_NULL = "(msg=null)";

    private static final int LONG_DIVIDE_SIZE = 2048;

    private static ThreadLocal<SoftReference<StringBuilder>> sLogBuffer =
        new ThreadLocalStringBuilder();

    public static int v(String tag, String msg) {
        return android.util.Log.v(tag, msg == null ? MSG_NULL : msg);
    }
    public static int v(String tag, String msg, Throwable tr) {
        return android.util.Log.v(tag, msg == null ? MSG_NULL : msg, tr);
    }
    public static int v(String tag, CharSequence msg) {
        return android.util.Log.v(tag, msg == null ? MSG_NULL : msg.toString());
    }
    public static int v(String tag, CharSequence msg, Throwable tr) {
        return android.util.Log.v(tag, msg == null ? MSG_NULL : msg.toString(), tr);
    }
    public static int d(String tag, String msg) {
        return android.util.Log.d(tag, msg == null ? MSG_NULL : msg);
    }
    public static int d(String tag, String msg, Throwable tr) {
        return android.util.Log.d(tag, msg == null ? MSG_NULL : msg, tr);
    }
    public static int d(String tag, CharSequence msg) {
        return android.util.Log.d(tag, msg == null ? MSG_NULL : msg.toString());
    }
    public static int d(String tag, CharSequence msg, Throwable tr) {
        return android.util.Log.d(tag, msg == null ? MSG_NULL : msg.toString(), tr);
    }
    public static int i(String tag, String msg) {
        return android.util.Log.i(tag, msg == null ? MSG_NULL : msg);
    }
    public static int i(String tag, String msg, Throwable tr) {
        return android.util.Log.i(tag, msg == null ? MSG_NULL : msg, tr);
    }
    public static int i(String tag, CharSequence msg) {
        return android.util.Log.i(tag, msg == null ? MSG_NULL : msg.toString());
    }
    public static int i(String tag, CharSequence msg, Throwable tr) {
        return android.util.Log.i(tag, msg == null ? MSG_NULL : msg.toString(), tr);
    }
    public static int w(String tag, String msg) {
        return android.util.Log.w(tag, msg == null ? MSG_NULL : msg);
    }
    public static int w(String tag, String msg, Throwable tr) {
        return android.util.Log.w(tag, msg == null ? MSG_NULL : msg, tr);
    }
    public static int w(String tag, CharSequence msg) {
        return android.util.Log.w(tag, msg == null ? MSG_NULL : msg.toString());
    }
    public static int w(String tag, CharSequence msg, Throwable tr) {
        return android.util.Log.w(tag, msg == null ? MSG_NULL : msg.toString(), tr);
    }
    public static int e(String tag, String msg) {
        return android.util.Log.e(tag, msg == null ? MSG_NULL : msg);
    }
    public static int e(String tag, String msg, Throwable tr) {
        return android.util.Log.e(tag, msg == null ? MSG_NULL : msg, tr);
    }
    public static int e(String tag, CharSequence msg) {
        return android.util.Log.e(tag, msg == null ? MSG_NULL : msg.toString());
    }
    public static int e(String tag, CharSequence msg, Throwable tr) {
        return android.util.Log.e(tag, msg == null ? MSG_NULL : msg.toString(), tr);
    }

    public static int vLong(String tag, String msg) {
        if (msg == null) {
            return v(tag, null);
        }
        int length = msg.length();
        if (length <= LONG_DIVIDE_SIZE) {
            return v(tag, msg);
        }
        int start = 0;
        int end = LONG_DIVIDE_SIZE;
        while (end < length) {
            v(tag, msg.substring(start, end));
            start = end;
            end += LONG_DIVIDE_SIZE;
        }
        return v(tag, msg.substring(start));
    }
    public static int vLong(String tag, CharSequence msg) {
        if (msg == null) {
            return v(tag, null);
        }
        int length = msg.length();
        if (length <= LONG_DIVIDE_SIZE) {
            return v(tag, msg);
        }
        int start = 0;
        int end = LONG_DIVIDE_SIZE;
        if (msg instanceof StringBuilder) {
            StringBuilder msgString = (StringBuilder) msg;
            while (end < length) {
                v(tag, msgString.substring(start, end));
                start = end;
                end += LONG_DIVIDE_SIZE;
            }
            return v(tag, msgString.substring(start));
        } else {
            String msgString = msg.toString();
            while (end < length) {
                v(tag, msgString.substring(start, end));
                start = end;
                end += LONG_DIVIDE_SIZE;
            }
            return v(tag, msgString.substring(start));
        }
    }
    public static int dLong(String tag, String msg) {
        if (msg == null) {
            return d(tag, null);
        }
        int length = msg.length();
        if (length <= LONG_DIVIDE_SIZE) {
            return d(tag, msg);
        }
        int start = 0;
        int end = LONG_DIVIDE_SIZE;
        while (end < length) {
            d(tag, msg.substring(start, end));
            start = end;
            end += LONG_DIVIDE_SIZE;
        }
        return d(tag, msg.substring(start));
    }
    public static int dLong(String tag, CharSequence msg) {
        if (msg == null) {
            return d(tag, null);
        }
        int length = msg.length();
        if (length <= LONG_DIVIDE_SIZE) {
            return d(tag, msg);
        }
        int start = 0;
        int end = LONG_DIVIDE_SIZE;
        if (msg instanceof StringBuilder) {
            StringBuilder msgString = (StringBuilder) msg;
            while (end < length) {
                d(tag, msgString.substring(start, end));
                start = end;
                end += LONG_DIVIDE_SIZE;
            }
            return d(tag, msgString.substring(start));
        } else {
            String msgString = msg.toString();
            while (end < length) {
                d(tag, msgString.substring(start, end));
                start = end;
                end += LONG_DIVIDE_SIZE;
            }
            return d(tag, msgString.substring(start));
        }
    }

    public static int vLines(String tag, String msg) {
        if (msg == null) {
            return v(tag, msg);
        }
        int length = msg.length();
        if (length < 2) {
            return v(tag, msg);
        }

        int written = 0;
        int start = 0;
        while (true) {
            int end = msg.indexOf('\n', start + 1);
            if (end < 0) {
                written += v(tag, msg.substring(start));
                break;
            }
            written += v(tag, msg.substring(start, end));
            start = end + 1;
        }
        return written;
    }
    public static int dLines(String tag, String msg) {
        if (msg == null) {
            return d(tag, msg);
        }
        int length = msg.length();
        if (length < 2) {
            return d(tag, msg);
        }

        int written = 0;
        int start = 0;
        while (true) {
            int end = msg.indexOf('\n', start + 1);
            if (end < 0) {
                written += d(tag, msg.substring(start));
                break;
            }
            written += d(tag, msg.substring(start, end));
            start = end + 1;
        }
        return written;
    }

    public static StringBuilder buf() {
        SoftReference<StringBuilder> ref = sLogBuffer.get();
        StringBuilder sb = (ref == null) ? null : ref.get();
        if (sb == null) {
            sb = new StringBuilder(ThreadLocalStringBuilder.DEFAULT_CAPACITY_SIZE);
            sLogBuffer.set(new SoftReference<StringBuilder>(sb));
        } else {
            sb.setLength(0);
        }
        return sb;
    }
}
