package com.jld.vod.utils

import android.os.SystemClock
import android.util.Log
import java.util.*

/**
 * @author ZhaoFuXin
 * @Email：18276061387@163.com
 * @description:
 * @date :2019/11/26 14:42
 */
object LogUtils {
    var TAG = "Debuger"

    val LOG_LEVEL_VERBOSE = 1
    val LOG_LEVEL_INFO = 2
    val LOG_LEVEL_DEBUG = 3
    val LOG_LEVEL_WARRING = 4
    val LOG_LEVEL_ERROR = 5
    val LOG_LEVEL_WTF = 6

    val THIS_CLASS_NAME = "net.vodlauncher.Debuger"

    private val sDebug = true
    private val sTagDefaut = false
    private val sLogLevel = LOG_LEVEL_VERBOSE

    fun setTag(tag: String) {
        TAG = tag
    }

    private fun logPass(level: Int): Boolean {
        if (!sDebug) return false
        return if (level >= sLogLevel) {
            true
        } else {
            false
        }
    }

    fun logV(msg: String?) {
        logV(TAG, msg)
    }

    fun logV(tag: String?, msg: String?) {
        if (logPass(LOG_LEVEL_VERBOSE)) {
            Log.v(if (sTagDefaut) TAG else tag, buildMessage(msg))
        }
    }

    fun logD(msg: String?) {
        logD(TAG, msg)
    }

    fun logD(tag: String?, msg: String?) {
        if (logPass(LOG_LEVEL_DEBUG)) {
            Log.d(if (sTagDefaut) TAG else tag, buildMessage(msg))
        }
    }

    fun logI(msg: String?, i: Int) {
        logI(TAG, msg)
    }

    fun logI(tag: String?, msg: String?) {
        if (logPass(LOG_LEVEL_INFO)) {
            Log.i(if (sTagDefaut) TAG else tag, buildMessage(msg))
        }
    }

    fun logW(msg: String?) {
        logW(TAG, msg)
    }

    fun logW(tag: String?, msg: String?) {
        if (logPass(LOG_LEVEL_WARRING)) {
            Log.w(if (sTagDefaut) TAG else tag, buildMessage(msg))
        }
    }

    fun logE(msg: String?) {
        logE(TAG, msg)
    }

    fun logE(tag: String?, msg: String?) {
        if (logPass(LOG_LEVEL_ERROR)) {
            Log.e(if (sTagDefaut) TAG else tag, buildMessage(msg))
        }
    }

    fun logWTF(msg: String?) {
        logWTF(TAG, msg)
    }

    fun logWTF(tag: String?, msg: String?) {
        if (logPass(LOG_LEVEL_WTF)) {
            Log.wtf(if (sTagDefaut) TAG else tag, buildMessage(msg))
        }
    }

    fun mark() {
        mark("")
    }

    fun mark(msg: String) {
        mark(TAG, msg)
    }

    fun mark(tag: String?, msg: String) {
        val time = "mark at time=" + SystemClock.elapsedRealtime()
        val trace =
            Throwable().fillInStackTrace().stackTrace
        var file: String? = null
        var className: String? = null
        var methodName: String? = null
        var lineNum: Long = -1
        for (i in 2 until trace.size) {
            className = trace[i].className
            if (!className.equals(THIS_CLASS_NAME, ignoreCase = true)) {
                file = trace[i].fileName
                methodName = trace[i].methodName
                lineNum = trace[i].lineNumber.toLong()
                break
            }
        }
        val out = String.format(
            Locale.US, "<tid=%d>[%s][%s][%d]:%s",
            Thread.currentThread().id, file, methodName, lineNum, time + msg
        )
        Log.d(if (sTagDefaut) TAG else tag, out)
    }

    fun printCurrentStack() {
        printCurrentStack(TAG)
    }

    fun printCurrentStack(tag: String?) {
        val trace =
            Throwable().fillInStackTrace().stackTrace
        for (i in 2 until trace.size) {
            val className = trace[i].className
            if (!className.equals(THIS_CLASS_NAME, ignoreCase = true)) {
                val file = trace[i].fileName
                val methodName = trace[i].methodName
                val lineNum = trace[i].lineNumber.toLong()
                val msg = String.format(
                    Locale.US, "<tid=%d>[%s][%s][%s][%d]",
                    Thread.currentThread().id, file, className, methodName, lineNum
                )
                Log.d(if (sTagDefaut) TAG else tag, msg)
            }
        }
    }

    private fun buildMessage(msg: String?): String? {
        val trace =
            Throwable().fillInStackTrace().stackTrace
        var file: String? = null
        var className: String? = null
        var methodName: String? = null
        var lineNum: Long = -1
        for (i in 2 until trace.size) {
            className = trace[i].className
            if (!className.equals(THIS_CLASS_NAME, ignoreCase = true)) {
                file = trace[i].fileName
                methodName = trace[i].methodName
                lineNum = trace[i].lineNumber.toLong()
                break
            }
        }
        return String.format(
            Locale.US, "<tid=%d>[%s][%s][%d]:%s",
            Thread.currentThread().id, file, methodName, lineNum, msg
        )
    }
}