package com.gh.common.exposure

import android.text.TextUtils
import com.g00fy2.versioncompare.Version
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.entity.ApkEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.manager.PackagesManager
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity

object ExposureUtils {

    private val mDownloadCompleteTraceEventIdSet = FixedSizeLinkedHashSet<String>(3)

    @JvmStatic
    fun logADownloadExposureEvent(
        entity: GameEntity,
        platform: String?,
        traceEvent: ExposureEvent?,
        downloadType: DownloadType
    ): ExposureEvent {
        val gameEntity = entity.clone()
        gameEntity.id = if (entity.id.contains(DownloadEntity.GAME_ID_DIVIDER)) {
            entity.id.split(DownloadEntity.GAME_ID_DIVIDER).toTypedArray()[0]
        } else {
            entity.id
        }
        gameEntity.gameVersion = entity.getApk().elementAtOrNull(0)?.version
            ?: gameEntity.gameVersion
        gameEntity.platform = platform
        gameEntity.downloadType = downloadType.toString()
        val exposureEvent = ExposureEvent.createEvent(
            gameEntity = gameEntity,
            source = traceEvent?.source ?: ArrayList(),
            eTrace = ExposureTraceUtils.appendTrace(traceEvent),
            event = ExposureType.DOWNLOAD
        )
        if (!TextUtils.isEmpty(entity.id)) {
            ExposureManager.log(exposureEvent)
        }
        return exposureEvent
    }

    @JvmStatic
    fun logADownloadCompleteExposureEvent(
        entity: GameEntity,
        platform: String?,
        trace: String?,
        host: String? = "unknown",
        path: String? = "unknown",
        downloadType: DownloadType
    ) {
        val gameEntity = entity.clone()
        gameEntity.platform = platform
        gameEntity.downloadCompleteType = downloadType.toString()
        val traceEvent = trace?.toObject<ExposureEvent>()

        if (TextUtils.isEmpty(entity.id)) return

        // 避免生成 trace 相同的下载完成事件，根据日志看下载完成的同一秒有可能生成两条
        if (mDownloadCompleteTraceEventIdSet.contains(traceEvent?.id)) {
            return
        }

        traceEvent?.payload?.gameId?.let { mDownloadCompleteTraceEventIdSet.add(it) }

        val exposureEvent = ExposureEvent.createEvent(
            gameEntity = gameEntity,
            source = traceEvent?.source ?: ArrayList(),
            eTrace = ExposureTraceUtils.appendTrace(traceEvent),
            event = ExposureType.DOWNLOAD_COMPLETE
        )
        exposureEvent.payload.host = host
        exposureEvent.payload.path = path
        ExposureManager.log(exposureEvent)
        ExposureManager.commitSavedExposureEvents(forcedUpload = true)
    }

    @JvmStatic
    fun getDownloadType(apkEntity: ApkEntity, gameId: String, isVGame: Boolean): DownloadType {
        return when {
            isVGame -> getVGameDownloadType(apkEntity, gameId)
            PackageUtils.isInstalled(
                HaloApp.getInstance().application,
                apkEntity.packageName
            ) -> getInstallDownloadType(apkEntity, gameId)
            else -> DownloadType.DOWNLOAD
        }
    }

    private fun getVGameDownloadType(apkEntity: ApkEntity, gameId: String): DownloadType {
        return when {
            PackagesManager.isCanUpdate(gameId, apkEntity.packageName) -> DownloadType.FUN_UPDATE
            else -> DownloadType.FUN_DOWNLOAD
        }
    }

    private fun getInstallDownloadType(apkEntity: ApkEntity, gameId: String): DownloadType {
        return when {
            PackageUtils.isSignedByGh(
                HaloApp.getInstance().application,
                apkEntity.packageName
            ) -> getUpdateDownloadType(apkEntity, gameId)
            !TextUtils.isEmpty(apkEntity.ghVersion) -> DownloadType.PLUGIN_DOWNLOAD
            else -> DownloadType.UPDATE
        }
    }

    private fun getUpdateDownloadType(apkEntity: ApkEntity, gameId: String): DownloadType {
        return when {
            PackageUtils.isCanUpdate(apkEntity, gameId) -> DownloadType.PLUGIN_UPDATE
            Version(apkEntity.version).isHigherThan(PackageUtils.getVersionNameByPackageName(apkEntity.packageName)) -> DownloadType.UPDATE
            else -> DownloadType.DOWNLOAD
        }
    }

    /**
     * 为游戏实体添加位置序号和上层专题 id (若存在)
     */
    @JvmStatic
    fun updateExposureInfo(
        gameList: List<GameEntity>?,
        subjectId: String? = null,
        containerId: String? = null,
        containerType: String? = null
    ) {
        gameList?.let {
            for ((index, game) in it.withIndex()) {
                game.sequence = index
                game.subjectId = subjectId
                game.containerId = containerId
                game.containerType = containerType
            }
        }
    }

    enum class DownloadType {
        DOWNLOAD,

        UPDATE,

        PLUGIN_UPDATE,

        PLUGIN_DOWNLOAD,

        FUN_DOWNLOAD,

        FUN_UPDATE
    }
}