package com.seatel.mobilehall.data.network

import android.content.Context
import android.content.pm.PackageInfo
import com.jaredrummler.android.device.DeviceName.DeviceInfo
import com.jaredrummler.android.device.DeviceName
import android.content.pm.PackageManager
import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import android.util.Log
import java.io.*
import java.lang.Exception
import java.lang.StringBuilder
import java.net.HttpURLConnection
import java.net.URL
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.concurrent.Callable
import java.util.concurrent.Executors

object Devices {
    var mMarketName: DeviceInfo? = null
    val deviceModel: String
        get() {
            val mModel: String
            mModel = Build.MODEL
            return mModel
        }

    fun getDeviceID(context: Context): String {
        val mModel: String
        mModel = Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
        return mModel
    }

    fun getDeviceInfo(context: Context?) {
        if (mMarketName == null) {
            DeviceName.with(context)
                .request { info, error ->
                    if (error == null && null != info) {
                        mMarketName = info
                    }
                }
        }
    }

    fun getDevicePublicIP(context: Context?): String? {
        var value: String? = null
        val es = Executors.newSingleThreadExecutor()
        val result = es.submit(Callable {
            try {
                val url = URL("http://whatismyip.akamai.com/")
                val urlConnection = url.openConnection() as HttpURLConnection
                try {
                    val `in`: InputStream = BufferedInputStream(urlConnection.inputStream)
                    val r = BufferedReader(InputStreamReader(`in`))
                    val total = StringBuilder()
                    var line: String?
                    while (r.readLine().also { line = it } != null) {
                        total.append(line).append('\n')
                    }
                    urlConnection.disconnect()
                    return@Callable total.toString()
                } finally {
                    urlConnection.disconnect()
                }
            } catch (e: IOException) {
                Log.e("Public IP: ", e.message!!)
            }
            null
        })
        try {
            value = result.get()
        } catch (e: Exception) {
            // failed
        }
        es.shutdown()
        return value
    }

    val marketName: String
        get() = if (mMarketName != null) {
            mMarketName!!.marketName
        } else {
            ""
        }
    val deviceOSVersion: String
        get() {
            val mOSVersion: String
            mOSVersion = Build.VERSION.RELEASE
            return mOSVersion
        }
    val deviceSDKVersion: Int
        get() {
            val mSdkVersion: Int
            mSdkVersion = Build.VERSION.SDK_INT
            return mSdkVersion
        }
    val deviceName: String
        get() {
            val manufacturer = Build.MANUFACTURER
            val model = Build.MODEL
            return if (model.startsWith(manufacturer)) {
                capitalize(model)
            } else capitalize(manufacturer) + " " + model
        }

    private fun capitalize(str: String): String {
        if (TextUtils.isEmpty(str)) {
            return str
        }
        val arr = str.toCharArray()
        var capitalizeNext = true
        var phrase = ""
        for (c in arr) {
            if (capitalizeNext && Character.isLetter(c)) {
                phrase += Character.toUpperCase(c)
                capitalizeNext = false
                continue
            } else if (Character.isWhitespace(c)) {
                capitalizeNext = true
            }
            phrase += c
        }
        return phrase
    }

    fun getAppVersionName(context: Context): String {
        try {
            return context.packageManager.getPackageInfo(
                context.packageName, 0
            ).versionName
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return "0.0"
    }

    fun getAppVersionCode(context: Context): Int {
        val manager = context.packageManager
        var info: PackageInfo? = null
        try {
            info = manager.getPackageInfo(
                context.packageName, 0
            )
            return info.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return 0
    }

    val deviceBrand: String
        get() {
            var mBrand = "UNKNOWN"
            mBrand = Build.BOARD
            return mBrand
        }
    val deviceProductName: String
        get() {
            var mBrand = "UNKNOWN"
            mBrand = Build.PRODUCT
            return mBrand
        }

    /***
     * This Method user for get Application Hast Key in Base 64
     *
     * @param context
     */
    fun getAppHashKey(context: Context) {
        try {
            val info = context.packageManager.getPackageInfo(
                context.packageName, PackageManager.GET_SIGNATURES
            )
            for (signature in info.signatures) {
                val md = MessageDigest.getInstance("SHA")
                md.update(signature.toByteArray())
            }
        } catch (e: PackageManager.NameNotFoundException) {
        } catch (e: NoSuchAlgorithmException) {
        }
    }

    val isEmulator: Boolean
        get() = (Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.startsWith("unknown")
                || Build.MODEL.contains("google_sdk")
                || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion")
                || Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
                || "google_sdk" == Build.PRODUCT)
}