package %your.logger.package%

private const val MAX_TAG_LENGTH = 23
private const val INLINE_CALL_STACK_INDEX = 2
private val ANONYMOUS_CLASS = Pattern.compile("(\\$\\d+)+$")

inline fun log(message: () -> Any?) {
    Log.d(inlineTag, message().toString())
}

inline fun loge(message: () -> Any?) {
    Log.e(inlineTag, message().toString())
}

inline fun loge(error: Throwable, message: () -> Any?) {
    Log.e(inlineTag, message().toString(), error)
}

val inlineTag: String
    get() {
        val stackTraceTag = createInlineStackElementTag()
        // Tag length limit was removed in API 24.
        return if (stackTraceTag.length <= MAX_TAG_LENGTH || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            stackTraceTag
        } else {
            stackTraceTag.substring(0, MAX_TAG_LENGTH)
        }
    }

fun createInlineStackElementTag(): String {
    val stackTrace = Throwable().stackTrace
    check(stackTrace.size > INLINE_CALL_STACK_INDEX) { "Synthetic stacktrace didn't have enough elements: are you using proguard?" }
    val element = stackTrace[INLINE_CALL_STACK_INDEX]
    var tag = "${element.className.substringAfterLast('.')}.${element.methodName}"
    val m = ANONYMOUS_CLASS.matcher(tag)
    if (m.find()) {
        tag = m.replaceAll("")
    }
    return tag
}