package com.example.studyapp.update

import android.util.Log
import com.example.studyapp.task.AfInfo
import com.example.studyapp.task.BigoInfo
import com.example.studyapp.task.DeviceInfo
import com.example.studyapp.task.TaskUtil
import com.example.studyapp.utils.ShellUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject

object UpdateUtil {
    val scope = CoroutineScope(Dispatchers.IO)
    fun changeDevice(
        recordPackageName: String,
        bigoDeviceObject: JSONObject?,
        afDeviceObject: JSONObject?,
        time: String,
        callback: ChangeCallBack
    ) {
        try {
            val padCode = ShellUtils.execRootCmdAndGetResult("getprop ro.boot.pad_code")
            Log.d("TAG", "changeDevice: $padCode")
            val jsonObject = JSONObject().apply {
                put("padCodes", JSONArray().apply {
                    put(padCode)
                })
            }
            var timeZone: String = ""
            bigoDeviceObject?.apply {

                val cpuClockSpeed: String = bigoDeviceObject.optString("cpu_clock_speed")
                val gaid: String = bigoDeviceObject.optString("gaid")
                val userAgent: String = bigoDeviceObject.optString("User-Agent")
                val osLang: String = bigoDeviceObject.optString("os_lang")
                val osVer: String = bigoDeviceObject.optString("os_ver")
                timeZone = bigoDeviceObject.optString("tz")
                val systemCountry: String = bigoDeviceObject.optString("system_country")
                val simCountry: String = bigoDeviceObject.optString("sim_country")
                val romFreeIn: Long = bigoDeviceObject.optLong("rom_free_in")
                val resolution: String = bigoDeviceObject.optString("resolution")
                val vendor: String = bigoDeviceObject.optString("vendor")
                val batteryScale: Int = bigoDeviceObject.optInt("bat_scale")

                val net: String = bigoDeviceObject.optString("net")
                val dpi: Int = bigoDeviceObject.optInt("dpi")
                val romFreeExt: Long = bigoDeviceObject.optLong("rom_free_ext")
                val dpiF: String = bigoDeviceObject.optString("dpi_f")
                val cpuCoreNum: Int = bigoDeviceObject.optInt("cpu_core_num")

                val bigoDevice = BigoInfo()
                bigoDevice.cpuClockSpeed = cpuClockSpeed
                bigoDevice.gaid = gaid
                bigoDevice.userAgent = userAgent
                bigoDevice.osLang = osLang
                bigoDevice.osVer = osVer
                bigoDevice.tz = timeZone
                bigoDevice.systemCountry = systemCountry
                bigoDevice.simCountry = simCountry
                bigoDevice.romFreeIn = romFreeIn
                bigoDevice.resolution = resolution
                bigoDevice.vendor = vendor
                bigoDevice.batteryScale = batteryScale
                bigoDevice.net = net
                bigoDevice.dpi = dpi.toLong()
                bigoDevice.romFreeExt = romFreeExt
                bigoDevice.dpiF = dpiF
                bigoDevice.cpuCoreNum = cpuCoreNum.toLong()
                TaskUtil.setBigoDevice(bigoDevice)
            }
            afDeviceObject?.apply {
                val advertiserId = afDeviceObject.optString(".advertiserId")
                val model = afDeviceObject.optString(".model")
                val brand = afDeviceObject.optString(".brand")
                val androidId = afDeviceObject.optString(".android_id")
                val xPixels = afDeviceObject.optInt(".deviceData.dim.x_px")
                val yPixels = afDeviceObject.optInt(".deviceData.dim.y_px")
                val densityDpi = afDeviceObject.optInt(".deviceData.dim.d_dpi")
                val country = afDeviceObject.optString(".country")
                val batteryLevel = afDeviceObject.optString(".batteryLevel")
                val stackInfo = Thread.currentThread().getStackTrace()[2].toString()
                val product = afDeviceObject.optString(".product")
                val network = afDeviceObject.optString(".network")
                val langCode = afDeviceObject.optString(".lang_code")
                val cpuAbi = afDeviceObject.optString(".deviceData.cpu_abi")
                val yDp = afDeviceObject.optInt(".deviceData.dim.ydp")
                val lang = afDeviceObject.optString(".lang")
                val ro_product_brand = afDeviceObject.optString("ro.product.brand", "")
                val ro_product_model = afDeviceObject.optString("ro.product.model", "")
                val ro_product_manufacturer =
                    afDeviceObject.optString("ro.product.manufacturer", "")
                val ro_product_device = afDeviceObject.optString("ro.product.device", "")
                val ro_product_name = afDeviceObject.optString("ro.product.name", "")
                val ro_build_version_incremental =
                    afDeviceObject.optString("ro.build.version.incremental", "")
                val ro_build_fingerprint = afDeviceObject.optString("ro.build.fingerprint", "")
                val ro_odm_build_fingerprint =
                    afDeviceObject.optString("ro.odm.build.fingerprint", "")
                val ro_product_build_fingerprint =
                    afDeviceObject.optString("ro.product.build.fingerprint", "")
                val ro_system_build_fingerprint =
                    afDeviceObject.optString("ro.system.build.fingerprint", "")
                val ro_system_ext_build_fingerprint =
                    afDeviceObject.optString("ro.system_ext.build.fingerprint", "")
                val ro_vendor_build_fingerprint =
                    afDeviceObject.optString("ro.vendor.build.fingerprint", "")
                val ro_build_platform = afDeviceObject.optString("ro.board.platform", "")
                val persist_sys_cloud_drm_id =
                    afDeviceObject.optString("persist.sys.cloud.drm.id", "")
                val persist_sys_cloud_battery_capacity =
                    afDeviceObject.optInt("persist.sys.cloud.battery.capacity", -1)
                val persist_sys_cloud_gpu_gl_vendor =
                    afDeviceObject.optString("persist.sys.cloud.gpu.gl_vendor", "")
                val persist_sys_cloud_gpu_gl_renderer =
                    afDeviceObject.optString("persist.sys.cloud.gpu.gl_renderer", "")
                val persist_sys_cloud_gpu_gl_version =
                    afDeviceObject.optString("persist.sys.cloud.gpu.gl_version", "")
                val persist_sys_cloud_gpu_egl_vendor =
                    afDeviceObject.optString("persist.sys.cloud.gpu.egl_vendor", "")
                val persist_sys_cloud_gpu_egl_version =
                    afDeviceObject.optString("persist.sys.cloud.gpu.egl_version", "")
                val global_android_id = afDeviceObject.optString(".android_id", "")
                val anticheck_pkgs = afDeviceObject.optString(".anticheck_pkgs", "")
                val pm_list_features = afDeviceObject.optString(".pm_list_features", "")
                val pm_list_libraries = afDeviceObject.optString(".pm_list_libraries", "")
                val system_http_agent = afDeviceObject.optString("system.http.agent", "")
                val webkit_http_agent = afDeviceObject.optString("webkit.http.agent", "")
                val com_fk_tools_pkgInfo = afDeviceObject.optString(".pkg_info", "")
                val appsflyerKey = afDeviceObject.optString(".appsflyerKey", "")
                val appUserId = afDeviceObject.optString(".appUserId", "")
                val disk = afDeviceObject.optString(".disk", "")
                val operator = afDeviceObject.optString(".operator", "")
                val cell_mcc = afDeviceObject.optString(".cell.mcc", "")
                val cell_mnc = afDeviceObject.optString(".cell.mnc", "")
                val date1 = afDeviceObject.optString(".date1", "")
                val date2 = afDeviceObject.optString(".date2", "")
                val bootId = afDeviceObject.optString("BootId", "")
                if (time.isNotEmpty()){
                    timeZone = time
                }
                val afDevice = AfInfo()
                afDevice.advertiserId = advertiserId
                afDevice.model = model
                afDevice.brand = brand
                afDevice.androidId = androidId
                afDevice.xPixels = xPixels
                afDevice.yPixels = yPixels
                afDevice.densityDpi = densityDpi
                afDevice.country = country
                afDevice.batteryLevel = batteryLevel
                afDevice.stackInfo = stackInfo
                afDevice.product = product
                afDevice.network = network
                afDevice.langCode = langCode
                afDevice.cpuAbi = cpuAbi
                afDevice.yDp = yDp.toLong()
                TaskUtil.setAfDevice(afDevice)

                val deviceInfo = DeviceInfo()
                deviceInfo.lang = lang
                deviceInfo.roProductBrand = ro_product_brand
                deviceInfo.roProductModel = ro_product_model
                deviceInfo.roProductManufacturer = ro_product_manufacturer
                deviceInfo.roProductDevice = ro_product_device
                deviceInfo.roProductName = ro_product_name
                deviceInfo.roBuildVersionIncremental = ro_build_version_incremental
                deviceInfo.roBuildFingerprint = ro_build_fingerprint
                deviceInfo.roOdmBuildFingerprint = ro_odm_build_fingerprint
                deviceInfo.roProductBuildFingerprint = ro_product_build_fingerprint
                deviceInfo.roSystemBuildFingerprint = ro_system_build_fingerprint
                deviceInfo.roSystemExtBuildFingerprint = ro_system_ext_build_fingerprint
                deviceInfo.roVendorBuildFingerprint = ro_vendor_build_fingerprint
                deviceInfo.roBuildPlatform = ro_build_platform
                deviceInfo.persistSysCloudDrmId = persist_sys_cloud_drm_id
                deviceInfo.persistSysCloudBatteryCapacity = persist_sys_cloud_battery_capacity
                deviceInfo.persistSysCloudGpuGlVendor = persist_sys_cloud_gpu_gl_vendor
                deviceInfo.persistSysCloudGpuGlRenderer = persist_sys_cloud_gpu_gl_renderer
                deviceInfo.persistSysCloudGpuGlVersion = persist_sys_cloud_gpu_gl_version
                deviceInfo.persistSysCloudGpuEglVendor = persist_sys_cloud_gpu_egl_vendor
                deviceInfo.persistSysCloudGpuEglVersion = persist_sys_cloud_gpu_egl_version
                TaskUtil.setDeviceInfo(deviceInfo)
                jsonObject.apply {
                    put("modemPropertiesList", JSONArray().apply {
                        put(JSONObject().apply {
                            put("propertiesName", "MCCMNC")
                            put("propertiesValue", "${cell_mcc},${cell_mnc}")
                        })
                    })
                    put("systemPropertiesList", JSONArray().apply {
                        put(JSONObject().apply {
                            put("propertiesName", "ro.product.manufacturer")
                            put("propertiesValue", ro_product_manufacturer)
                        })
                        put(JSONObject().apply {
                            put("propertiesName", "ro.product.brand")
                            put("propertiesValue", ro_product_brand)
                        })
                        put(JSONObject().apply {
                            put("propertiesName", "ro.product.model")
                            put("propertiesValue", ro_product_model)
                        })
//                        put(JSONObject().apply {
//                            put("propertiesName", "ro.build.display.id")
//                            put("propertiesValue", )
//                        })
                        put(JSONObject().apply {
                            put("propertiesName", "ro.product.name")
                            put("propertiesValue", ro_product_name)
                        })
                        put(JSONObject().apply {
                            put("propertiesName", "ro.product.device")
                            put("propertiesValue", ro_product_device)
                        })
//                        put(JSONObject().apply {
//                            put("propertiesName", "ro.product.board")
//                            put("propertiesValue", bo)
//                        })
//                    put(JSONObject().apply {
//                        put("propertiesName", "ro.build.tags")
//                        put("propertiesValue", )
//                    })
                        put(JSONObject().apply {
                            put("propertiesName", "ro.build.fingerprint")
                            put("propertiesValue", ro_build_fingerprint)
                        })
//                        put(JSONObject().apply {
//                            put("propertiesName", "ro.build.date.utc")
//                            put("propertiesValue", da)
//                        })
//                        put(JSONObject().apply {
//                            put("propertiesName", "ro.build.user")
//                            put("propertiesValue", user)
//                        })
//                    put(JSONObject().apply {
//                        put("propertiesName", "ro.build.host")
//                        put("propertiesValue", device.expand.)
//                    })
//                        put(JSONObject().apply {
//                            put("propertiesName", "ro.build.description")
//                            put("propertiesValue", des)
//                        })
                        put(JSONObject().apply {
                            put("propertiesName", "ro.build.version.incremental")
                            put("propertiesValue", ro_build_version_incremental)
                        })
//                    put(JSONObject().apply {
//                        put("propertiesName", "ro.build.version.codename")
//                        put("propertiesValue", device.cod)
//                    })
                    })
                    put("settingPropertiesList", JSONArray().apply {
                        put(JSONObject().apply {
                            put("propertiesName", "ssaid/${recordPackageName}")
                            put("propertiesValue", androidId)
                        })
//                        put(JSONObject().apply {
//                            put("propertiesName", "bt/mac")
//                            put("propertiesValue", mac)
//                        })
                        put(JSONObject().apply {
                            put("propertiesName", "language")
                            put("propertiesValue", langCode)
                        })
                        put(JSONObject().apply {
                            put("propertiesName", "timezone")
                            put("propertiesValue", timeZone)
                        })
//                    put(JSONObject().apply {
//                        put("propertiesName", "systemvolume")
//                        put("propertiesValue", device.expand.)
//                    })
                    })
                    put("oaidPropertiesList", JSONArray().apply {
                        put(JSONObject().apply {
                            put("propertiesName", "AAID")
                            put("propertiesValue", advertiserId)
                        })
                    })
                }
            }

            val jsonString = jsonObject.toString()
            val response = Api.updatePad(jsonString)
            val dataList = response.data
            if (response.isSuccess() && dataList != null && dataList.isNotEmpty()) {
                val padTask = dataList[0]
                scope.launch {
                    Log.d("TAG", "changeDevice: $padTask")
                    var loop = true
                    while (loop) {
                        delay(5000)
                        val result = Api.padTaskDetail(padTask.taskId)
                        if (result == 3) {
                            Log.d(
                                "ChangeDeviceInfoUtil",
                                "changeDeviceInfo changeDeviceInfo success"
                            )
                            loop = false
                            callback.changeSuccess()
                        } else if (result == -1) {
                            Log.d("ChangeDeviceInfoUtil", "changeDeviceInfo changeDeviceInfo fail")
                            loop = false
                            callback.changeFailed()
                        }
                    }
                }
            }
        } catch (e: JSONException) {
            e.printStackTrace()
            callback.changeFailed()
        }
    }
}