package com.gh.gamecenter.setting.compose

import android.os.Build
import androidx.multidex.MultiDexApplication
import com.alibaba.android.arouter.launcher.ARouter
import com.facebook.animated.giflite.GifDecoder
import com.facebook.common.logging.FLog
import com.facebook.imageformat.DefaultImageFormats
import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.facebook.imagepipeline.core.ImageTranscoderType
import com.facebook.imagepipeline.core.MemoryChunkType
import com.facebook.imagepipeline.decoder.ImageDecoderConfig
import com.gh.gamecenter.common.image.EmptyDecoder
import com.gh.gamecenter.common.utils.ImageUtils.disableAnimatedImage
import com.gh.gamecenter.common.utils.ImageUtils.isFrescoInitialized
import com.gh.gamecenter.core.iinterface.IApplication
import com.github.piasy.biv.BigImageViewer
import com.github.piasy.biv.loader.fresco.FrescoImageLoader
import java.util.*

class SettingModuleApp : MultiDexApplication() {

    private val mApplicationList = ServiceLoader.load(IApplication::class.java, this.javaClass.classLoader)

    override fun onCreate() {
        super.onCreate()
        initArouter()
        mApp = this
        for (application in mApplicationList) {
            application.onCreate(this)
        }
        initFresco()
        DataUtils.init(this, "")
    }

    private fun initArouter() {
        if (BuildConfig.DEBUG) {  // 这两行必须写在init之前，否则这些配置在init过程中将无效
            ARouter.openLog() // 打印日志
            ARouter.openDebug() // 开启调试模式(如果在InstantRun模式下运行，必须开启调试模式！线上版本需要关闭,否则有安全风险)
        }
        ARouter.init(this) // 尽可能早，推荐在Application中初始化
    }

    fun initFresco() {
        // 初始化 Fresco(BigImageViewer 已包含Fresco)
        if (!isFrescoInitialized()) {
            // 在 5.0 & 5.1 设备上 disable native code，原因是应用附带了 arm64 的 SO 以后在部分 5.0/5.1 设备
            // 会出现找不到 arm64 so 的情况，具体可见
            // https://sentry.ghzs.com/organizations/lightgame/issues/53107/
            // 所以这里尝试在 5.0 & 5.1 设备上关闭 fresco 的 native 解码，应该会让 5.0 & 5.1 的设备 OOM 概率提高，但先试试效果
            // 同时禁用动图
            val pipelineConfigBuilder = ImagePipelineConfig.newBuilder(this)
            val decodeConfigBuilder = ImageDecoderConfig.newBuilder()
            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
                || Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1
            ) {
                pipelineConfigBuilder.setMemoryChunkType(MemoryChunkType.BUFFER_MEMORY)
                    .setImageTranscoderType(ImageTranscoderType.JAVA_TRANSCODER)
                decodeConfigBuilder.overrideDecoder(DefaultImageFormats.GIF, GifDecoder()).build()
                val manufacture = Build.MANUFACTURER.lowercase(Locale.getDefault())

                // OPPO 和 VIVO 的 5.1.1 设备还会去加载 WEBP_ANIMATED 的 SO，
                // 实测没有发现有地方使用 WEBP_ANIMATED 的图片，这里用空占位图来替换 WEBP 动图
                if ("oppo" == manufacture || "vivo" == manufacture) {
                    decodeConfigBuilder.overrideDecoder(
                        DefaultImageFormats.WEBP_ANIMATED,
                        EmptyDecoder()
                    ).build()
                }
                pipelineConfigBuilder
                    .setImageDecoderConfig(decodeConfigBuilder.build())
                    .experiment()
                    .setNativeCodeDisabled(true)

                // 图片仅加载静态图片
                disableAnimatedImage()
            }
            try {
                BigImageViewer.initialize(
                    FrescoImageLoader.with(
                        this,
                        pipelineConfigBuilder.build()
                    )
                )
            } catch (e: Throwable) {
                e.printStackTrace()
            }
            FLog.setMinimumLoggingLevel(FLog.VERBOSE)
        }
    }

    companion object {
        private lateinit var mApp: SettingModuleApp

        fun getInstance(): SettingModuleApp {
            return mApp
        }
    }
}