package com.ydl.ydlcommon.app

import android.content.Context
import com.apm.insight.MonitorCrash
import com.apm.insight.log.VLog
import com.bytedance.apm.insight.ApmInsight
import com.bytedance.apm.insight.ApmInsightAgent
import com.bytedance.apm.insight.ApmInsightInitConfig
import com.bytedance.apm.insight.IDynamicParams
import com.meituan.android.walle.WalleChannelReader
import org.json.JSONObject

object Apm {

    private var crash: MonitorCrash? = null

    private var hasInit = false

    fun initApm(context: Context, appId: String, vCode: Long, vName: String, debug: Boolean, uidCall: () -> String?) {
        if (debug) return
        val channel = if (debug) "debug" else WalleChannelReader.getChannel(context)
        crash = MonitorCrash.init(
            context,
            appId,
            vCode,
            vName
        )
        crash?.config()?.setChannel(channel)
        val builder = ApmInsightInitConfig.builder()
            .aid(appId)
            //.batteryMonitor(true)
            //.cpuMonitor(true)
            //.fpsMonitor(true)
            //.seriousBlockDetect(true)
            .blockDetect(false)
//            .enableWebViewMonitor(true)
            .channel(channel)
            .debugMode(debug)
            .enableLogRecovery(true)
            .setDynamicParams(ApmParams(crash, uidCall))
        ApmInsight.getInstance().init(context, builder.build())
        VLog.init(context, 20)
        hasInit = true
    }

    fun reportCustom(type: String, msg: String, throwable: Throwable) {
        if (hasInit) {
            crash?.reportCustomErr(msg, type, throwable)
        }
    }

    fun reportEvent(event: String, dimension: String, value: String) {
        try {
            if (hasInit) {
                val d = hashMapOf(dimension to value)
                ApmInsightAgent.monitorEvent(event, d, hashMapOf())
            }
        } catch (throwable: Throwable) {
            VLog.e("reportEvent", throwable.message)
        }
    }

    fun reportEventWithExt(event: String, dimension: String, value: String, ext: Map<String, String>) {
        try {
            if (hasInit) {
                val d = hashMapOf(dimension to value)
                if (ext.isNotEmpty()) {
                    val json = JSONObject(ext)
                    ApmInsightAgent.monitorEvent(event, d, hashMapOf(), json)
                } else {
                    ApmInsightAgent.monitorEvent(event, d, hashMapOf())
                }
            }
        } catch (throwable: Throwable) {
            VLog.e("reportEvent", throwable.message)
        }
    }
}

private class ApmParams(val crash: MonitorCrash?, val uidCall: () -> String?) : IDynamicParams() {
    override fun getUserUniqueID(): String? {
        return null
    }

    override fun getAbSdkVersion(): String? {
        return null
    }

    override fun getSsid(): String? {
        return null
    }

    override fun getDid(): String? {
        return null
    }

    override fun getUserId(): String? {
        val uid = uidCall.invoke()
        crash?.config()?.setUID(uid)
        return uid
    }
}