package flutter.guru.guru_applovin_flutter.log

import android.content.Context
import android.os.Environment
import java.io.File
import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicBoolean
import java.util.logging.FileHandler
import java.util.logging.Level
import java.util.logging.Logger

object Logger {

    private const val verbose = 0
    private const val debug = 1
    private const val info = 2
    private const val warning = 3
    private const val error = 4
    private const val wtf = 5

    private val levelTaps = arrayOf("V", "D", "I", "W", "E", "WTF")

    private const val LOGS_DIRECTORY = "guru/logs"
    private val defaultLevel = object : Level("default", 2629, "guru.ads.max.flutter") {}
    private val initialized = AtomicBoolean(false)
    private var logger: Logger? = null
    private val deliverExecutor = Executors.newSingleThreadExecutor()

    fun initialize(context: Context) {
        if (!initialized.compareAndSet(false, true)) {
            return
        }
        val resolvedLogsDirectory = File(
            if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState() && !Environment.isExternalStorageRemovable()) {
                context.getExternalFilesDir(null)
            } else {
                context.filesDir
            }, LOGS_DIRECTORY
        ).also { it.mkdirs() }

        val debugApp = SystemProperties.read("debug.guru.ads.max.flutter")
        val forceDebug = true //debugApp == context.packageName
        val filePattern = resolvedLogsDirectory.path + "/" + "flutter-max"
        logger = Logger.getLogger("flutter-max").also {
            kotlin.runCatching {
                FileHandler(filePattern, 1024 * 1024 * 10, 7, true)
            }.getOrNull()?.let { fileHandler ->
                fileHandler.formatter = MainFormatter()
                it.useParentHandlers = forceDebug
                it.addHandler(fileHandler)
            }
        }
    }

    private fun log(tag: String, level: Int, message: String) {
        deliverExecutor.execute {
            logger?.log(defaultLevel, "[$tag] ${levelTaps[level]} $message")
        }
    }

    fun v(tag: String, message: String) {
        log(tag, verbose, message)
    }

    fun d(tag: String, message: String) {
        log(tag, debug, message)
    }

    fun i(tag: String, message: String) {
        log(tag, info, message)
    }

    fun w(tag: String, message: String) {
        log(tag, warning, message)
    }

    fun e(tag: String, message: String) {
        log(tag, error, message)
    }

    fun wtf(tag: String, message: String) {
        log(tag, wtf, message)
    }

}