package com.gh.common.util

import com.gh.common.constant.Config
import com.gh.common.exposure.ExposureUtils
import com.gh.common.simulator.SimulatorDownloadManager
import com.gh.common.simulator.SimulatorGameManager
import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadDataHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.eventbus.EBShowDialog
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.dsp.DspReportHelper
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.entity.CustomPageTrackData
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.SimulatorEntity
import com.gh.gamecenter.feature.utils.PlatformUtils
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.pkg.PkgHelper
import com.gh.ndownload.NDownloadBridge
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus

object DownloadObserver {

    private val mApplication = HaloApp.getInstance().application

    // 简单 debounce 因为内存更新 downloadEntity 对象造成的触发双重下载完成事件
    // TODO 修复因为更改内存对象造成的双重下载完成事件问题，具体触发代码见 DownloadDao.updateSnapshotList
    private var mDoneDebouncePair: Pair<String, Long>? = null

    private const val TAG = "DownloadObserver"
    private const val CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED = "CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED"

    private val mRetryableHashMap = hashMapOf<String, Boolean>()
    private val mRetryableProgressMap = hashMapOf<String, Long>()

    /**
     * 当下载任务是 预约上线提醒 触发的，则所有弹窗均不显示
     */
    private val DownloadEntity.isDownloadByReserveOnlineReminder: Boolean
        get() = !meta?.get(Constants.IS_RESERVE_ONLINE_REMINDER).isNullOrBlank()

    // 如果在WIFI状态下,下载自动暂停,则再重试一遍
    @JvmStatic
    fun initObserver() {
        val dataWatcher = object : DataWatcher() {
            override fun onDataChanged(downloadEntity: DownloadEntity) {
                // todo 如何处理xapk安装问题
                val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
                if (!xapkStatus.isNullOrEmpty()) return

                val gameId = downloadEntity.gameId
                val downloadManager = DownloadManager.getInstance()

                tryCatchInRelease {
                    DownloadDataHelper.uploadDownloadEvent(downloadEntity)
                }

                val status = downloadEntity.status

                if (DownloadStatus.hijack == status) {
                    // 链接被劫持
                    if (downloadEntity.isDownloadByReserveOnlineReminder) {
                        return
                    }
                    processHijack(downloadEntity)
                    return
                } else if (DownloadStatus.notfound == status) {
                    // 404 Not Found
                    // 删除任务
                    downloadEntity.status = DownloadStatus.cancel
                    downloadManager.cancel(downloadEntity.url)
                    Utils.toast(mApplication, "该链接已失效！请联系管理员。")

                    val currentActivity = AppManager.getInstance().currentActivity() ?: return

                    SensorsBridge.trackDownloadLinkRotDialogShow(
                        gameId = downloadEntity.gameId,
                        gameName = downloadEntity.name,
                        gameType = downloadEntity.categoryChinese
                    )
                    if (downloadEntity.isDownloadByReserveOnlineReminder) {
                        return
                    }
                    DialogHelper.showDialog(
                        currentActivity,
                        "下载失败",
                        "下载链接已失效，建议提交反馈",
                        "立即反馈",
                        "取消",
                        confirmClickCallback = {
                            HelpAndFeedbackBridge.startSuggestionActivity(
                                currentActivity,
                                SuggestType.GAME, "notfound",
                                "问题反馈：下载链接失效",
                                SimpleGameEntity(gameId, downloadEntity.name, "")
                            )
                            SensorsBridge.trackDownloadLinkRotDialogClick(
                                buttonName = "立即反馈",
                                gameId = downloadEntity.gameId,
                                gameName = downloadEntity.name,
                                gameType = downloadEntity.categoryChinese
                            )
                        },
                        cancelClickCallback = {
                            SensorsBridge.trackDownloadLinkRotDialogClick(
                                buttonName = "取消",
                                gameId = downloadEntity.gameId,
                                gameName = downloadEntity.name,
                                gameType = downloadEntity.categoryChinese
                            )
                        },
                        touchOutsideCallback = {
                            SensorsBridge.trackDownloadLinkRotDialogClick(
                                buttonName = "关闭弹窗",
                                gameId = downloadEntity.gameId,
                                gameName = downloadEntity.name,
                                gameType = downloadEntity.categoryChinese
                            )
                        },
                        extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
                    )
                    return
                } else if (DownloadStatus.neterror == status
                    || DownloadStatus.diskioerror == status
                    || DownloadStatus.timeout == status
                ) {
                    if (mRetryableHashMap[downloadEntity.url] == true
                        && (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
                                || NDownloadBridge.isDownloadViaTrafficAllowed(downloadEntity))
                    ) {
                        downloadManager.resumeDownload(downloadEntity.url)
                        mRetryableHashMap[downloadEntity.url] = false
                        Utils.log(TAG, "下载重试->" + downloadEntity.toJson())
                    } else {
                        if (DownloadStatus.diskioerror == status) {
                            ToastUtils.toast("磁盘 IO 异常，请稍后重试")
                        } else {
                            ToastUtils.toast("网络不稳定，下载任务已暂停")
                        }

                        DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
                        Utils.log(TAG, "下载自动暂停->" + downloadEntity.toJson())
                    }
                } else if (DownloadStatus.diskisfull == status) {
                    ToastUtils.toast("磁盘已满，请清理空间后重试下载")

                    downloadManager.pause(downloadEntity.url)
                } else if (DownloadStatus.redirected == status) {
                    Utils.log(TAG, "重定向完毕")
                    DownloadDataHelper.uploadRedirectEvent(downloadEntity)
                } else if (DownloadStatus.unqualified == status) {
                    // 未成年
                    if (!downloadEntity.isDownloadByReserveOnlineReminder) {
                        RealNameHelper.showRealNameUnqualifiedDialog(downloadEntity)
                    }

                    // 删除任务
                    downloadEntity.status = DownloadStatus.cancel
                    downloadManager.cancel(downloadEntity.url)
                } else if (DownloadStatus.unavailable == status) {
                    // 未接入防沉迷系统
                    val currentActivity = AppManager.getInstance().currentActivity()

                    if (currentActivity != null && !downloadEntity.isDownloadByReserveOnlineReminder) {
                        DialogHelper.showDialog(
                            context = currentActivity,
                            title = "温馨提示",
                            content = "该游戏未接入防沉迷系统，暂不支持下载",
                            confirmText = "知道了",
                            cancelText = ""
                        )
                    } else {
                        ToastUtils.toast("该游戏未接入防沉迷系统，暂不支持下载")
                    }

                    // 删除任务
                    downloadEntity.status = DownloadStatus.cancel
                    downloadManager.cancel(downloadEntity.url)
                } else if (DownloadStatus.isCertificating == status) {
                    // 未接入防沉迷系统
                    val currentActivity = AppManager.getInstance().currentActivity()

                    if (currentActivity != null && !downloadEntity.isDownloadByReserveOnlineReminder) {
                        DialogHelper.showDialog(
                            context = currentActivity,
                            title = "实名提示",
                            content = "您当前的身份信息正在认证中，根据相关政策要求，该游戏需通过认证后才能进行下载",
                            cancelText = "知道了",
                            confirmText = "查看实名认证",
                            cancelClickCallback = null,
                            confirmClickCallback = {
                                currentActivity.startActivity(
                                    ShellActivity.getIntent(
                                        currentActivity,
                                        ShellActivity.Type.REAL_NAME_INFO,
                                    )
                                )
                            }
                        )
                    } else {
                        ToastUtils.toast("您当前的身份信息正在认证中，根据相关政策要求，该游戏需通过认证后才能进行下载")
                    }

                    // 删除任务
                    downloadEntity.status = DownloadStatus.cancel
                    downloadManager.cancel(downloadEntity.url)
                } else if (DownloadStatus.uncertificated == status) {
                    // 未实名
                    if (!downloadEntity.isDownloadByReserveOnlineReminder) {
                        RealNameHelper.showRealNameUncertificatedDialog(downloadEntity)
                    }

                    // 删除任务
                    downloadEntity.status = DownloadStatus.cancel
                    downloadManager.cancel(downloadEntity.url)
                } else if (DownloadStatus.banned == status) {
                    ToastUtils.showToast("网络异常")
                    // 删除任务
                    downloadEntity.status = DownloadStatus.cancel
                    downloadManager.cancel(downloadEntity.url)
                }

                if (DownloadStatus.done == status) {
                    if (mDoneDebouncePair?.first != downloadEntity.url) {
                        mDoneDebouncePair = Pair(downloadEntity.url, System.currentTimeMillis())
                        // 清理临时变量
                        downloadEntity.addMetaExtra(Constants.IS_RESERVE_ONLINE_REMINDER, "")
                        performDownloadCompleteAction(downloadEntity, downloadManager)
                    } else {
                        if (mDoneDebouncePair?.second == 0L
                            || System.currentTimeMillis() - (mDoneDebouncePair?.second ?: 0) > 500
                        ) {
                            // 清理临时变量
                            downloadEntity.addMetaExtra(Constants.IS_RESERVE_ONLINE_REMINDER, "")
                            performDownloadCompleteAction(downloadEntity, downloadManager)
                        }
                    }

                    mRetryableHashMap.remove(downloadEntity.url)
                    mRetryableProgressMap.remove(downloadEntity.url)

                    EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", downloadEntity.packageName, ""))
                }

                DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)

                // 如果已下载大小发生变化,表示成功恢复下载,则重置重试标记
                if (status == DownloadStatus.downloading
                    && downloadEntity.progress != mRetryableProgressMap[downloadEntity.url]) {
                    mRetryableProgressMap[downloadEntity.url] = downloadEntity.progress
                    mRetryableHashMap[downloadEntity.url] = true
                }
            }
        }

        // 添加观察者
        DownloadManager.getInstance().addObserver(dataWatcher)
    }

    private fun performDownloadCompleteAction(
        downloadEntity: DownloadEntity,
        downloadManager: DownloadManager,
    ) {
        if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
            statDoneEvent(downloadEntity)
            // 会有 ActivityNotFoundException 异常，catch 掉不管了
            tryWithDefaultCatch {
                if (Constants.SILENT_UPDATE != downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)) {
                    NewFlatLogUtils.logGameInstall(
                        gameId = downloadEntity.gameId ?: "",
                        gameName = downloadEntity.name ?: "",
                        trigger = "自动安装"
                    )

                    SensorsBridge.trackInstallGameClick(
                        gameName = downloadEntity.name,
                        gameId = downloadEntity.gameId,
                        action = "自动安装",
                        isDspGame = downloadEntity.getMetaExtra(Constants.DSP_GAME) == "true",
                        dspAdId = downloadEntity.getMetaExtra(Constants.DSP_AD_ID)
                    )

                    // TODO 在 Android 11 上没有授权安装未知应用的权限前第一次调用这个方法系统会杀掉我们的进程...
                    // 没能找到类似的解释，最接近的是这个 https://issuetracker.google.com/issues/154157387，但也只是点授权杀进程而已
                    PackageInstaller.install(mApplication, downloadEntity);
                    DataLogUtils.uploadUpgradeLog(mApplication, "install") //上传更新安装数据
                }
            }
        } else {
            statDoneEvent(downloadEntity)

            logCoreEventIfNeeded(downloadEntity.getGameCategory())

            GameActivityDownloadHelper.clear()

            val platform = PlatformUtils.getInstance(mApplication)
                .getPlatformName(downloadEntity.platform)
            if (platform != null) {
                when {
                    // TODO 插件化传 path 从 apk 中获取 packageName 的形式有可能出现拿不到 packageName 的情况
                    downloadEntity.isPluggable -> // 弹出插件化提示框
                        EventBus.getDefault().post(
                            EBShowDialog(
                                BaseActivity.PLUGGABLE,
                                downloadEntity.path,
                                downloadEntity
                            )
                        )

                    downloadEntity.isPlugin -> Utils.toast(
                        mApplication,
                        downloadEntity.name + " - " + platform + " - 下载完成"
                    )

                    else -> {
                        if (!downloadEntity.asVGame()) {
                            Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
                        }
                    }
                }
            } else {
                if (!downloadEntity.asVGame()) {
                    Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
                }
            }
            if (!downloadEntity.isPluggable) {
                if (downloadEntity.isSimulatorGame()) {
                    val simulatorJson = downloadEntity.getMetaExtra(Constants.SIMULATOR)
                    val gameName = downloadEntity.getMetaExtra(Constants.GAME_NAME)
                    if (simulatorJson.isEmpty()) return
                    var simulator = GsonUtils.fromJson(simulatorJson, SimulatorEntity::class.java)
                    val isInstalledNewSimulator =
                        SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
                    val isInstalledOldSimulator =
                        SimulatorGameManager.isOldSimulatorInstalled(HaloApp.getInstance().application)
                    val currentActivity = AppManager.getInstance().currentActivity()
                        ?: return
                    val newSimulator = Config.getNewSimulatorEntitySetting()
                    if ((!isInstalledOldSimulator && newSimulator != null && newSimulator.active) || isInstalledNewSimulator) { //如果没有安装任一旧的模拟器 或者下载了新模拟器 则使用新版本模拟器
                        simulator = newSimulator ?: simulator
                    }
                    SimulatorDownloadManager.getInstance().showDownloadDialog(
                        currentActivity,
                        simulator,
                        SimulatorDownloadManager.SimulatorLocation.LAUNCH,
                        downloadEntity.gameId,
                        gameName,
                        downloadEntity.categoryChinese,
                        null
                    )
                    SimulatorGameManager.recordDownloadSimulatorGame(downloadEntity.gameId, simulator.type)
                    SimulatorGameManager.postPlayedGame(downloadEntity.gameId, downloadEntity.packageName)
                } else {
                    val downloadType = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
                    // 是否是自动安装
                    val isAutoInstall = SPUtils.getBoolean(Constants.SP_AUTO_INSTALL, true)
                    if (downloadType != Constants.VSPACE_32_DOWNLOAD_ONLY && (downloadType == Constants.SIMULATOR_DOWNLOAD || isAutoInstall)) {
                        if (FileUtils.isEmptyFile(downloadEntity.path)) {
                            Utils.toast(mApplication, com.gh.gamecenter.common.R.string.install_failure_hint)
                            downloadManager.cancel(downloadEntity.url)
                        } else {
                            if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)
                                || downloadType == Constants.VGAME
                                || downloadType == Constants.DUAL_DOWNLOAD_VGAME
                            ) {
                                downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
                                tryWithDefaultCatch {
                                    NewFlatLogUtils.logGameInstall(
                                        gameId = downloadEntity.gameId ?: "",
                                        gameName = downloadEntity.name ?: "",
                                        trigger = "自动安装"
                                    )

                                    SensorsBridge.trackInstallGameClick(
                                        gameId = downloadEntity.gameId,
                                        gameName = downloadEntity.name,
                                        action = "自动安装",
                                        isDspGame = downloadEntity.getMetaExtra(Constants.DSP_GAME) == "true",
                                        dspAdId = downloadEntity.getMetaExtra(Constants.DSP_AD_ID)
                                    )
                                    PackageInstaller.install(mApplication, downloadEntity, false, ignoreAsVGame = false)
                                }
                            } else {
                                // 弹出卸载提示框
                                if (downloadEntity.isPlugin) {
                                    EventBus.getDefault().post(
                                        EBShowDialog(
                                            BaseActivity.PLUGGABLE,
                                            downloadEntity.path,
                                            downloadEntity
                                        )
                                    )
                                } else {
                                    EventBus.getDefault().post(
                                        EBShowDialog(
                                            BaseActivity.SIGNATURE_CONFLICT,
                                            downloadEntity.path,
                                            downloadEntity
                                        )
                                    )
                                }
                            }
                        }
                    }
                }
            }
        }

        // 下载过程分析统计

        // 部分设备 (已知 vivo 5.1.1) 在调用 packageManager.getPackageArchiveInfo 获取比较大的 APK 文件时会出现 ANR
        // 这里为了让它能用就不判断是否解析包错误了
        if (PackageUtils.isDeviceUnableToHandleBigApkFile(downloadEntity.path)) {
            return
        }

        val pm = mApplication.packageManager
        val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, 0)
        if (packageInfo == null) {
            val downloadType = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
            if (downloadType == Constants.SIMULATOR_DOWNLOAD) {
                val currentActivity = AppManager.getInstance().currentActivity()
                    ?: return
                DialogUtils.showSimulatorParseErrorDialog(
                    currentActivity,
                    downloadEntity.gameId,
                    downloadEntity.name,
                    object : ConfirmListener {
                        override fun onConfirm() {
                            val simulator = HaloApp.get(downloadEntity.name, true) as? SimulatorEntity
                                ?: return
                            DownloadManager.getInstance().cancel(downloadEntity.url, true, true, false)
                            SimulatorDownloadManager.getInstance()
                                .showDownloadDialog(
                                    currentActivity,
                                    simulator,
                                    SimulatorDownloadManager.SimulatorLocation.SIMULATOR_GAME
                                )
                        }
                    })
            }
        }
    }

    // 统计下载完成事件
    private fun statDoneEvent(downloadEntity: DownloadEntity) {
        var type: ExposureUtils.DownloadType
        if (downloadEntity.isUpdate) {
            if (downloadEntity.asVGame()) {
                type = ExposureUtils.DownloadType.FUN_UPDATE
            } else {
                type = ExposureUtils.DownloadType.UPDATE
                if (downloadEntity.isPlugin) {
                    type = ExposureUtils.DownloadType.PLUGIN_UPDATE
                }
            }
        } else {
            type = if (downloadEntity.asVGame()) {
                ExposureUtils.DownloadType.FUN_DOWNLOAD
            } else {
                ExposureUtils.DownloadType.DOWNLOAD
            }
        }

        if (downloadEntity.isPluggable) {
            type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD
        }

        var downloadSpeed = 0L
        val elapsedTimeString = downloadEntity.meta[DownloadConfig.KEY_DOWNLOAD_ELAPSED_TIME]
        if (elapsedTimeString != null) {
            var elapsedTime = elapsedTimeString.toLong()
            if (elapsedTime == 0L) {
                elapsedTime = 1L
            }
            downloadSpeed = downloadEntity.size / elapsedTime
        }

        val isPlatformRecommend =
            java.lang.Boolean.parseBoolean(downloadEntity.getMetaExtra(Constants.IS_PLATFORM_RECOMMEND))
        val adGroupId = downloadEntity.getMetaExtra(Constants.AD_GROUP_ID)
        val exposureEvent = ExposureUtils.logADownloadCompleteExposureEvent(
            GameEntity(
                _id = downloadEntity.gameId,
                mName = downloadEntity.name.removeSuffix(Constants.GAME_NAME_DECORATOR),
                gameVersion = downloadEntity.versionName ?: "",
                isPlatformRecommend = isPlatformRecommend,
                adIconActive = downloadEntity.meta[Constants.AD_ICON_ACTIVE].toBoolean(),
                isAdData = downloadEntity.meta[Constants.IS_AD_DATA].toBoolean(),
                downloadUrl = downloadEntity.meta[Constants.DOWNLOAD_URL]
            ),
            downloadEntity.platform,
            downloadEntity.exposureTrace,
            downloadSpeed,
            downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown",
            downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown",
            downloadEntity.meta[NDownloadBridge.REDIRECTED_URL_LIST] ?: "unknown",
            type
        )

        if (downloadEntity.asVGame()) {
            val customTrackDataJson = downloadEntity.customPageTrackDataJson
            val kvs = if (customTrackDataJson.isNullOrBlank()) {
                arrayOf<String>()
            } else {
                GsonUtils.fromJson(customTrackDataJson, CustomPageTrackData::class.java).toKV()
            }
            SensorsBridge.trackEventWithExposureSource(
                "HaloFunGameDownloadDone",
                exposureEvent?.source,
                "game_name", downloadEntity.name,
                "game_id", downloadEntity.gameId,
                "game_type", downloadEntity.categoryChinese,
                "game_schema_type", if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
                "is_ad", if (adGroupId.isEmpty()) "false" else "true",
                "ad_group_id", adGroupId,
                *kvs
            )
        } else if (downloadEntity.gameId == Constants.HALO_FUN_GAME_ID) {
            SensorsBridge.trackEvent(
                "HaloFunDownloadDone",
                "space_schema_type",
                if (downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) "32位" else "64位"
            )
        } else if (downloadEntity.gameId == Constants.HALO_FUN_NEW_32_GAME_ID) {
            SensorsBridge.trackEvent(
                "HaloFunDownloadDone",
                "space_schema_type",
                "32位(新)"
            )
        }

        if (downloadEntity.gameId != Constants.GHZS_GAME_ID
            && downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SIMULATOR_DOWNLOAD
            && downloadEntity.gameId != Constants.HALO_FUN_GAME_ID
            && downloadEntity.gameId != Constants.HALO_FUN_NEW_32_GAME_ID
        ) {
            val trackJson = downloadEntity.customPageTrackDataJson
            val kvs = if (!trackJson.isNullOrBlank()) {
                GsonUtils.fromJson(trackJson, CustomPageTrackData::class.java).toKV()
            } else {
                arrayOf()
            }

            val pushMessageId = (HaloApp.get(Constants.PUSH_MESSAGE_ID, false) as? String) ?: ""
            val pushLinkId = (HaloApp.get(Constants.PUSH_LINK_ENTITY, false) as? LinkEntity)?.link ?: ""
            val isFromPush = pushMessageId.isNotEmpty()

            if (downloadEntity.getMetaExtra(Constants.DSP_GAME) != "true") {
                SensorsBridge.trackEventWithExposureSource(
                    "DownloadProcessFinish",
                    exposureEvent?.source,
                    "game_id",
                    downloadEntity.gameId,
                    "game_name",
                    downloadEntity.meta[Constants.GAME_NAME] ?: "",
                    "game_type",
                    downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
                    "game_label",
                    downloadEntity.tags.joinToString(","),
                    "game_schema_type",
                    if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
                    "page_name",
                    getCurrentPageEntity().pageName,
                    "page_id",
                    getCurrentPageEntity().pageId,
                    "page_business_id",
                    getCurrentPageEntity().pageBusinessId,
                    "last_page_name",
                    getLastPageEntity().pageName,
                    "last_page_id",
                    getLastPageEntity().pageId,
                    "last_page_business_id",
                    getLastPageEntity().pageBusinessId,
                    "download_status",
                    downloadEntity.meta[Constants.DOWNLOAD_STATUS_IN_CHINESE] ?: "",
                    "download_type",
                    if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
                    "is_from_push_notifications",
                    isFromPush,
                    "is_ad", if (adGroupId.isEmpty()) "false" else "true",
                    "ad_group_id", adGroupId,
                    "message_id",
                    pushMessageId,
                    "link_id",
                    pushLinkId,
                    *kvs
                )
            } else {
                val searchContent = downloadEntity.getMetaExtra(Constants.SEARCH_KEY)

                SensorsBridge.trackEventWithExposureSource(
                    "DspAdDownloadFinish",
                    exposureEvent?.source,
                    "ad_id", downloadEntity.getMetaExtra(Constants.DSP_AD_ID),
                    "search_content", searchContent,
                    "game_column_name", downloadEntity.getMetaExtra(Constants.SUBJECT_NAME),
                    "game_column_id", downloadEntity.getMetaExtra(Constants.SUBJECT_ID),
                    "game_id", downloadEntity.gameId,
                    "game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
                    "game_type", downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
                    "game_label", downloadEntity.tags.joinToString(","),
                    "game_schema_type", if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
                    "page_name", getCurrentPageEntity().pageName,
                    "page_id", getCurrentPageEntity().pageId,
                    "page_business_id", getCurrentPageEntity().pageBusinessId,
                    "last_page_name", getLastPageEntity().pageName,
                    "last_page_id", getLastPageEntity().pageId,
                    "last_page_business_id", getLastPageEntity().pageBusinessId,
                    "download_status", downloadEntity.meta[Constants.DOWNLOAD_STATUS_IN_CHINESE] ?: "",
                    "download_type", if (downloadEntity.asVGame()) "畅玩下载" else "本地下载",
                    "is_from_push_notifications", isFromPush,
                    "message_id", pushMessageId,
                    "link_id", pushLinkId,
                    "location", if (searchContent.isEmpty()) "自定义页面" else "游戏搜索结果列表",
                    *kvs
                )

                DspReportHelper.report(downloadEntity.getMetaExtra(Constants.DOWNLOAD_URL))
            }
        }

        DataCollectionUtils.uploadDownload(mApplication, downloadEntity, "完成")
    }

    private fun processHijack(downloadEntity: DownloadEntity) {
        // 删除任务
        downloadEntity.status = DownloadStatus.cancel
        DownloadManager.getInstance().cancel(downloadEntity.url)
        // 弹出提示框
        EventBus.getDefault().post(EBShowDialog(BaseActivity.DOWNLOAD_HIJACK))
        // 记录链接被劫持
        DataCollectionUtils.uploadHijack(mApplication, downloadEntity)
        // 上传劫持log
        DataLogUtils.uploadHijack(mApplication, downloadEntity)
    }

    /**
     * 根据预设的游戏类型上报关键事件(下载完成事件)
     */
    private fun logCoreEventIfNeeded(gameCategory: String) {
        val category = PkgHelper.getCoreEventGameCategory()
        val categoryMatched = if (category == "standard" || category.isNullOrEmpty()) {
            true
        } else {
            gameCategory == category
        }

        if (!SPUtils.getBoolean(CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED) && categoryMatched) {
            HaloApp.getInstance().flavorProvider.logCoreEvent()
            SPUtils.setBoolean(CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED, true)
        }
    }

}