package com.genlot.ninglottery.toolkit;

import android.util.Log;

import com.genlot.nativesdk.SystemNI;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;

public class LogTool {
    private static final String mTag = "GtLogger";
    private static final int mLength = 100;
    private static final int LEVEL_VERBOSE = 1;
    private static final int LEVEL_DEBUG = 2;
    private static final int LEVEL_INFO = 3;
    private static final int LEVEL_WARN = 4;
    private static final int LEVEL_ERROR = 5;

    private static StackTraceElement getStackTraceElement() {
        return Thread.currentThread().getStackTrace()[5];
    }

    private static String logTime() {
        SimpleDateFormat simFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault());
        Date date = new Date(System.currentTimeMillis());
        return simFormat.format(date);
    }

    private static ArrayList<Integer> getSplitIndex(byte[] data, int splitSize) {
        ArrayList<Integer> _splitIndex = new ArrayList<>();
        int size = data.length;
        int index = 0;
        int offset = 0;
        while (index < size) {
            if (data[index] >= 0x20) {
                index++;
                offset++;
            } else {
                if ((data[index] & 0xF0) == 0x80) {
                    index++;
                    offset++;
                } else if ((data[index] & 0xF0) == 0xC0) {
                    index += 2;
                    offset += 2;
                } else if ((data[index] & 0xF0) == 0xE0) {
                    index += 3;
                    offset += 3;
                } else if ((data[index] & 0xF0) == 0xF0) {
                    index += 4;
                    offset += 4;
                } else {
                    index++;
                    offset++;
                }
            }
            if (offset >= splitSize) {
                offset = 0;
                _splitIndex.add(index);
            }
        }
        return _splitIndex;
    }

    private static void logLevel(int level, String tag, String msg) {
        switch (level) {
            case LEVEL_VERBOSE:
                Log.v(tag, msg);
                break;
            case LEVEL_DEBUG:
                Log.d(tag, msg);
                break;
            case LEVEL_INFO:
                Log.i(tag, msg);
                break;
            case LEVEL_WARN:
                Log.w(tag, msg);
                break;
            case LEVEL_ERROR:
                Log.e(tag, msg);
                break;
            default:
                break;
        }
    }

    private static void formatLog(int level, String tag, String msg) {
        StringBuffer buffer = new StringBuffer();
        //第一行
        buffer.append("┌");
        for (int i = 0; i < mLength; i++) {
            buffer.append("─");
        }
        buffer.append("┐");
        logLevel(level, mTag, buffer.toString());
        //打印第二行
        buffer.setLength(0);
        buffer.append("│");
        buffer.append(logTime());
        buffer.append(" (");
        buffer.append(tag);
        buffer.append(")  ");
        buffer.append("Tid:");
        buffer.append(android.os.Process.myTid());
        int length = buffer.toString().length();
        if (length < mLength + 1) {
            for (int i = 0; i < mLength + 1 - length; i++) {
                buffer.append(" ");
            }
        }
        logLevel(level, mTag, buffer.toString());
        //打印第三行
        buffer.setLength(0);
        buffer.append("├");
        for (int i = 0; i < mLength; i++) {
            buffer.append("─");
        }
        buffer.append("┤");
        logLevel(level, mTag, buffer.toString());
        //打印第四行-日志内容
        buffer.setLength(0);
        if (msg == null) {
            logLevel(level, mTag, buffer.toString());
            return;
        }
        byte[] data = msg.getBytes();
        length = data.length;
        if (length <= mLength) {
            buffer.append("│");
            buffer.append(msg);
            logLevel(level, mTag, buffer.toString());
        } else {
            int size = 0;
            ArrayList<Integer> splitIndex = getSplitIndex(data, mLength - 6);
            for (int i = 0; i < splitIndex.size(); i++) {
                buffer.setLength(0);
                buffer.append("│");
                if (i == 0) {
                    buffer.append(new String(data, 0, splitIndex.get(i)));
                } else {
                    size = splitIndex.get(i) - splitIndex.get(i - 1);
                    buffer.append(new String(data, splitIndex.get(i - 1), size));
                }
                logLevel(level, mTag, buffer.toString());
            }
            int index = splitIndex.get(splitIndex.size() - 1);
            if (index < length) {
                buffer.setLength(0);
                buffer.append("│");
                buffer.append(new String(data, index, data.length - index));
                logLevel(level, mTag, buffer.toString());
            }
        }
        buffer.setLength(0);
        buffer.append("└");
        for (int i = 0; i < mLength; i++) {
            buffer.append("─");
        }
        buffer.append("┘");
        logLevel(level, mTag, buffer.toString());
    }

    private static String tag() {
        String name = getStackTraceElement().getFileName();
        int lineNo = getStackTraceElement().getLineNumber();
        return name + ":" + lineNo;
    }

    public static void logV(String msg) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("☞");
        buffer.append("(");
        buffer.append(tag());
        buffer.append(")");
        buffer.append(" ");
        buffer.append(msg);
        Log.v(mTag, buffer.toString());
    }

    public static void logD(String msg) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("☞");
        buffer.append("(");
        buffer.append(tag());
        buffer.append(")");
        buffer.append(" ");
        buffer.append(msg);
        Log.d(mTag, buffer.toString());
    }

    public static void logI(String msg) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("☞");
        buffer.append("(");
        buffer.append(tag());
        buffer.append(")");
        buffer.append(" ");
        buffer.append(msg);
        Log.i(mTag, buffer.toString());
    }

    public static void logW(String msg) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("☞");
        buffer.append("(");
        buffer.append(tag());
        buffer.append(")");
        buffer.append(" ");
        buffer.append(msg);
        Log.w(mTag, buffer.toString());
        //formatLog(LEVEL_WARN, tag, msg);
    }

    public static void logE(String msg) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("☞");
        buffer.append("(");
        buffer.append(tag());
        buffer.append(")");
        buffer.append(" ");
        buffer.append(msg);
        Log.e(mTag, buffer.toString());
        //formatLog(LEVEL_ERROR, tag, msg);
        try {
            SystemNI.writeErrorLogFile(tag(), msg);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
