package com.ypsx.base.base

import android.app.Application
import android.content.Intent
import android.os.Build
import android.os.Process
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner
import com.elvishew.xlog.LogConfiguration
import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog
import com.elvishew.xlog.formatter.border.DefaultBorderFormatter
import com.elvishew.xlog.formatter.message.json.DefaultJsonFormatter
import com.elvishew.xlog.formatter.message.throwable.DefaultThrowableFormatter
import com.elvishew.xlog.formatter.message.xml.DefaultXmlFormatter
import com.elvishew.xlog.formatter.stacktrace.DefaultStackTraceFormatter
import com.elvishew.xlog.formatter.thread.DefaultThreadFormatter
import com.elvishew.xlog.printer.AndroidPrinter
import com.elvishew.xlog.printer.Printer
import com.elvishew.xlog.printer.file.FilePrinter
import com.elvishew.xlog.printer.file.backup.FileSizeBackupStrategy2
import com.elvishew.xlog.printer.file.backup.NeverBackupStrategy
import com.elvishew.xlog.printer.file.clean.FileLastModifiedCleanStrategy
import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator
import com.tencent.mmkv.MMKV
import com.ypsx.base.R
import com.ypsx.base.util.PathUtils
import com.ypsx.base.util.XLogFlattener

/**
 * 作者　: hegaojian
 * 时间　: 2019/12/14
 * 描述　: 对于写BaseApp，其实我是拒绝的，但是需要提供一个很有用的功能--在Activity/fragment中获取Application级别的ViewModel
 * 所以才硬着头皮加的，如果你不想继承BaseApp，又想获取Application级别的ViewModel功能
 * 那么你可以复制该类的代码到你的自定义Application中去，然后可以自己写获取ViewModel的拓展函数即 :
 * GetViewModelExt类的getAppViewModel方法
 */

open class BaseApp : Application(), ViewModelStoreOwner {

    private val maxSize: Long = 1024 * 1024 * 50
    private val maxTimeMillis: Long = 1000 * 60 * 60 * 24 * 30
    private val maxBackupIndex: Int = 10

    private lateinit var mAppViewModelStore: ViewModelStore

    private var mFactory: ViewModelProvider.Factory? = null

    override fun getViewModelStore(): ViewModelStore {
        return mAppViewModelStore
    }

    override fun onCreate() {
        super.onCreate()
        MMKV.initialize(this)

        mAppViewModelStore = ViewModelStore()
        initXlog()
    }

    /**
     * 获取一个全局的ViewModel
     */
    fun getAppViewModelProvider(): ViewModelProvider {
        return ViewModelProvider(this, this.getAppFactory())
    }

    private fun getAppFactory(): ViewModelProvider.Factory {
        if (mFactory == null) {
            mFactory = ViewModelProvider.AndroidViewModelFactory.getInstance(this)
        }
        return mFactory as ViewModelProvider.Factory
    }

    private fun initXlog() {
        val config = LogConfiguration.Builder()
            .logLevel(LogLevel.ALL)// 指定日志级别，低于该级别的日志将不会被打印，默认为 LogLevel.ALL
            .tag(getString(R.string.global_tag)) // 指定 TAG，默认为 "X-LOG"
            .enableThreadInfo() // 允许打印线程信息，默认禁止
            .enableStackTrace(2) // 允许打印深度为 2 的调用栈信息，默认禁止
            .enableBorder() // 允许打印日志边框，默认禁止
            .jsonFormatter(DefaultJsonFormatter()) // 指定 JSON 格式化器，默认为 DefaultJsonFormatter
            .xmlFormatter(DefaultXmlFormatter()) // 指定 XML 格式化器，默认为 DefaultXmlFormatter
            .throwableFormatter(DefaultThrowableFormatter()) // 指定可抛出异常格式化器，默认为 DefaultThrowableFormatter
            .threadFormatter(DefaultThreadFormatter()) // 指定线程信息格式化器，默认为 DefaultThreadFormatter
            .stackTraceFormatter(DefaultStackTraceFormatter()) // 指定调用栈信息格式化器，默认为 DefaultStackTraceFormatter
            .borderFormatter(DefaultBorderFormatter()) // 指定边框格式化器，默认为 DefaultBorderFormatter
            .build()

        val androidPrinter: Printer = AndroidPrinter(true) // 通过 android.util.Log 打印日志的打印器

//        val consolePrinter: Printer = ConsolePrinter() // 通过 System.out 打印日志到控制台的打印器

        val filePrinter: Printer = FilePrinter.Builder(PathUtils.getLogParent()) // 指定保存日志文件的路径
            .fileNameGenerator(DateFileNameGenerator()) // 指定日志文件名生成器，默认为 ChangelessFileNameGenerator("log")
            .backupStrategy(NeverBackupStrategy()) // 指定日志文件备份策略，默认为 FileSizeBackupStrategy(1024 * 1024)
            .backupStrategy(
                FileSizeBackupStrategy2(maxSize, maxBackupIndex)
            )             // Default: FileSizeBackupStrategy(1024 * 1024)
            .cleanStrategy(FileLastModifiedCleanStrategy(maxTimeMillis))     // Default: NeverCleanStrategy(), 7天
            .flattener(XLogFlattener()) // 指定日志平铺器，默认为 DefaultFlattener
            .build()

        XLog.init( // 初始化 XLog
            config,  // 指定日志配置，如果不指定，会默认使用 new LogConfiguration.Builder().build()
            androidPrinter,  // 添加任意多的打印器。如果没有添加任何打印器，会默认使用 AndroidPrinter(Android)/ConsolePrinter(java)
            filePrinter
        )



    }


    /**
     * 重启当前应用
     */
    fun restartApplication() {
        val intent = packageManager.getLaunchIntentForPackage(packageName)
        intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        startActivity(intent)
        Process.killProcess(Process.myPid())
    }
}