package melody.offline.music.http

import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.media.MediaDrm
import android.os.Build
import android.telephony.TelephonyManager
import android.text.TextUtils
import melody.offline.music.App
import melody.offline.music.sp.AppStore
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.UUID

val packageName: String = App.app.packageName

fun getCountryCode(context: Context): String? {
    var countryCode = ""
    try {
        val telephonyManager =
            context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        countryCode = if (telephonyManager.phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
            val c = Class.forName("android.os.SystemProperties")
            val get = c.getMethod("get", String::class.java)

            // Gives MCC + MNC
            val homeOperator = get.invoke(c, "ro.cdma.home.operator.numeric") as String
            homeOperator.substring(0, 3) // the last three digits is MNC
        } else {
            val config = context.resources.configuration
            config.mcc.toString()
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return countryCode
}

fun getSimCountryIso(context: Context): String? {
    val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    return telephonyManager.simCountryIso
}

//获取国家代码
fun getCountry(context: Context): String? {
    return getSimCountryIso(context)
}


fun getAppVersionName(context: Context): String? {
    val packageManager = context.packageManager
    var packInfo: PackageInfo? = null
    try {
        packInfo = packageManager.getPackageInfo(context.packageName, 0)
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
    }
    return packInfo!!.versionName
}

fun getAppVersionCode(context: Context): Long {
    return try {
        val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            context.packageManager.getPackageInfo(context.packageName, PackageManager.PackageInfoFlags.of(0))
        } else {
            context.packageManager.getPackageInfo(context.packageName, 0)
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            packageInfo.longVersionCode
        } else {
            packageInfo.versionCode.toLong()
        }
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
        -1
    }
}

fun userID(context: Context): String {
    var id = ""
    if (TextUtils.isEmpty(AppStore(context).userID)) {
        val newID = UUID.randomUUID().toString()
        AppStore(context).userID = newID
    } else {
        id = AppStore(context).userID
    }
    return id
}

fun getUUId(ctx: Context): String {
    val cache = AppStore(ctx).appUUID
    return if (TextUtils.isEmpty(cache)) {
        val u = generateImmutableUUID(ctx)
        AppStore(ctx).appUUID = u
        u
    } else {
        cache
    }
}

fun generateImmutableUUID(context: Context): String {
    /*The Android ID
        * 通常被认为不可信，因为它有时为null。开发文档中说明了：这个ID会改变如果进行了出厂设置。
        * 并且，如果某个Andorid手机被Root过的话，这个ID也可以被任意改变。
        * */
    val m_szAndroidID = android.provider.Settings.Secure.getString(
        context.contentResolver,
        android.provider.Settings.Secure.ANDROID_ID
    )
    /*
     *Android系统2.3版本以上可以获取硬件Serial Number
     * 优点：非手机设备也可以通过该接口获取ID。
     * */
    var serial: String? = null
    serial = try {
        //API>=9 使用serial号
        android.os.Build::class.java.getField("SERIAL").get(null).toString()
    } catch (exception: Exception) {
        "serial" // serial需要一个初始化，随便一个初始化
    }

    //drm id
    var drmId: String = getDrmDeviceId()

    /*
     * 有一些特殊的情况，一些如平板电脑的设置没有通话功能，或者你不愿加入READ_PHONE_STATE许可。
     * 而你仍然想获得唯一序列号之类的东西。这时你可以通过取出ROM版本、制造商、CPU型号、以及其他硬件信息来实现这一点。
     * 这样计算出来的ID不是唯一的（因为如果两个手机应用了同样的硬件以及Rom 镜像）。
     * 但应当明白的是，出现类似情况的可能性基本可以忽略。要实现这一点，你可以使用Build类:
     * */
    val m_szDevIDShort = "666" +
            Build.HOST.length % 10 +
            Build.ID.length % 10 +
            Build.MANUFACTURER.length % 10 +
            Build.MODEL.length % 10 +
            Build.PRODUCT.length % 10 +
            Build.TAGS.length % 10 +
            Build.TYPE.length % 10 +
            Build.BOARD.length % 10 +
            Build.BRAND.length % 10 +
            Build.CPU_ABI.length % 10 +
            Build.DEVICE.length % 10 +
            Build.DISPLAY.length % 10 +
            Build.USER.length % 10 //13 digits

    val m_szLongID = serial + m_szDevIDShort + m_szAndroidID + drmId
    //md5加密生成唯一uuid
    var m: MessageDigest? = null
    try {
        m = MessageDigest.getInstance("MD5")
    } catch (e: NoSuchAlgorithmException) {
        e.printStackTrace()
    }

    m!!.update(m_szLongID.toByteArray(), 0, m_szLongID.length)
    // get md5 bytes
    val p_md5Data = m!!.digest()
    // create a hex string
    var m_szUniqueID = StringBuilder()
    for (aP_md5Data in p_md5Data) {
        val b = 0xFF and aP_md5Data.toInt()
        // if it is a single digit, make sure it have 0 in front (proper padding)
        if (b <= 0xF)
            m_szUniqueID.append("0")
        // add number to string
        m_szUniqueID.append(Integer.toHexString(b))
    }   // hex string to uppercase
    m_szUniqueID = StringBuilder(m_szUniqueID.toString().toLowerCase())
    return m_szUniqueID.toString()
}

private fun getDrmDeviceId(): String {
    var id = ""
    val WIDEVINE_UUID = UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L)
    val COMMON_PSSH_UUID = UUID(0x1077EFECC0B24D02L, -0x531cc3e1ad1d04b5L)
    val CLEARKEY_UUID = UUID(-0x1d8e62a7567a4c37L, 0x781AB030AF78D30EL)
    val PLAYREADY_UUID = UUID(-0x65fb0f8667bfbd7aL, -0x546d19a41f77a06bL)
    try {
        val bytesId = MediaDrm(WIDEVINE_UUID)
            .getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID)
        id = android.util.Base64.encodeToString(bytesId, android.util.Base64.NO_WRAP)
    } catch (ignore: Exception) {
    }
    return id
}