package com.lemonhc.mplus.framework.util.kotlinExtension

import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.util.Base64
import android.util.Log
import android.widget.Toast
import com.google.gson.Gson
import com.lemonhc.mplus.MPlusConstants.APP_NAME
import com.lemonhc.mplus.MPlusConstants.CERT_TYPE
import com.lemonhc.mplus.MPlusConstants.PLATFORM_TYPE
import com.lemonhc.mplus.MPlusConstants.UPDATE_MSG
import com.lemonhc.mplus.MPlusConstants.VERSION_URL
import com.lemonhc.mplus.classes.ResponseVersionCheck
import com.lemonhc.mplus.framework.task.ApiClient

import com.lemonhc.mplus.mcare_plus.activity.MainActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.apache.maven.artifact.versioning.DefaultArtifactVersion
import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.error
import java.io.File
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException

//모든 액티비티에 캡쳐 방지기능 추가
var Activity.isCaptureFlag: Boolean by FieldProperty { true }
val TAG: String = "ExtensionActivity"

fun Activity.versionCheck(){
    val req_param = mutableListOf<Pair<String, Any?>>().apply {
        add("platformType" to PLATFORM_TYPE)
        add("appName" to APP_NAME)
        add("certType" to CERT_TYPE)
    }
    Log.e(TAG, "reqParam -- > $req_param")

    if (isNetworkConnected) {
        /*
         * 버전체크 후 최신버전이 아닐경우,
         * 설치페이지로 보내주고(혹은 앱스토어) 앱은 종료한다.
         */
        ApiClient(VERSION_URL, req_param, header_param = mapOf("Content-Type" to "application/json"))
                .encType(ApiClient.ENC_Type.Json)
                .connect {
                    val json = it ?: kotlin.run {
                        //json 값이 실제로 들어있는지 체크하는 로직 추가
                        Toast.makeText(this, "서버와 통신이 원활하지 않습니다.", Toast.LENGTH_LONG).show()
                        return@connect
                    }

                    val responseVersionCheck = Gson().fromJson(json.toString(), ResponseVersionCheck::class.java)
                    var version = "-1"

                    try {
                        val i = this.packageManager.getPackageInfo(this.packageName, 0)
                        version = i.versionName
                    } catch (e: PackageManager.NameNotFoundException) {
                        e.printStackTrace()
                    }

                    val serverVersion = DefaultArtifactVersion(responseVersionCheck.versionOrder)
                    val deviceVersion = DefaultArtifactVersion(version)
                    Log.e("versionCheck", "serverVersion -- > $serverVersion")
                    Log.e("versionCheck", "deviceVersion -- > $deviceVersion")

                    val gap = serverVersion.compareTo(deviceVersion) // 서버가 크면 1, 작으면 -1, 같으면 0
                    if (gap > 0) {
                        val url = responseVersionCheck.marketUrl
                        Log.e(TAG, "url -- > $url")
                        val alert_confirm = AlertDialog.Builder(this)
                        alert_confirm.setMessage(UPDATE_MSG).setCancelable(false)
                                .setPositiveButton("확인") { dialog, which ->
                                    val intent = Intent(Intent.ACTION_VIEW)
                                    val uri = Uri.parse(url)
                                  Log.e("url", "url -- > $uri")
                                    intent.data = uri
                                    startActivity(intent)
                                    // finish() 를 호출하면 페이지를 열기전에 죽어버린다.
                                    android.os.Process.killProcess(android.os.Process.myPid())
                                }
                                .setNegativeButton("취소", DialogInterface.OnClickListener { dialog, which ->
                                    exit()
                                    return@OnClickListener
                                })
                        val alert = alert_confirm.create()
                        alert.show()
                    } else {
                        if(this::class.java.name != MainActivity::class.java.name){
                            moveToMain()
                        }
                    }
                }

    }else{
        Toast.makeText(this, "인터넷을 사용할 수 없습니다.", Toast.LENGTH_LONG).show()
        finish()
    }

}

fun Activity.chkSIGNATURES(){
    val chkSig = "40F9C161D58B6FB079095C90CD6BD195FA186F1F"
    try {
        val sig = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures
        sig.map {
            val digest = MessageDigest.getInstance("SHA")
            digest.update(it.toByteArray())
            val sig = bytesToHex(digest.digest())

            if (chkSig != sig){
                AnkoLogger("chkSig").error { chkSig }
                AnkoLogger("sig").error { sig }

                CoroutineScope(Dispatchers.Main).launch {
                    Toast.makeText(this@chkSIGNATURES, "앱이 변조되었습니다.", Toast.LENGTH_SHORT).show()
                    delay(1000)
                    exit()
                }
            }
        }

    }catch (e:PackageManager.NameNotFoundException){
        exit()
    }catch (e1:NoSuchAlgorithmException){
        exit()
    }
}



fun Activity.bytesToHex(bytes: ByteArray): String {
    val hexArray = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')
    val hexChars = CharArray(bytes.size * 2)
    var v: Int
    for (j in bytes.indices) {
        v = bytes[j].toInt() and 0xFF
        hexChars[j * 2] = hexArray[v.ushr(4)]
        hexChars[j * 2 + 1] = hexArray[v and 0x0F]
    }
    return String(hexChars)
}




//chkRooting
fun Activity.cpzmfnxld(){
    if(dlwmfnxld()){
        CoroutineScope(Dispatchers.Main).launch {
            Toast.makeText(this@cpzmfnxld, "루팅된 단말입니다.", Toast.LENGTH_SHORT).show()
            delay(1000)
            exit()
        }
    }
}

/**
 * 시스템이 루팅여부 확인
 * @return
 * isRooting
 */
fun Activity.dlwmfnxld(): Boolean {
    /*
        boolean result = false;
        // 명령어 체크
        result = isRootingCheckCmd();
        // 파일 체크
        result = isRootingCheckFile();
        return result;
        */
    return if (dlwmfnxldcpzmzjaosem() == true || dlwmfnxldcpzmvkdlf() == true) true else false
}

/**
 * 루팅체크 (명령어)
 * @return
 * isRootingCheckCmd
 */
private fun Activity.dlwmfnxldcpzmzjaosem(): Boolean {
    var result: Boolean
    try {
        // 루트권한 획득했는지 명령어로 체크
        Runtime.getRuntime().exec(this.byteArrayToString(arrayListOf(115, 117)))
        result = true
    } catch (ex: Exception) {
        result = false
    }

    return result
}

/**
 * 루팅체크 (파일)
 * @return
 * isRootingCheckFile
 */
private fun Activity.dlwmfnxldcpzmvkdlf(): Boolean {

    val arrayOfString = arrayOf(
            this.byteArrayToString(arrayListOf(47, 115, 98, 105, 110, 47, 115, 117)),
            this.byteArrayToString(arrayListOf(47, 115, 121, 115, 116, 101, 109, 47, 115, 117)),
            this.byteArrayToString(arrayListOf(47, 115, 121, 115, 116, 101, 109, 47, 98, 105, 110, 47, 115, 117)),
            this.byteArrayToString(arrayListOf(47, 115, 121, 115, 116, 101, 109, 47, 115, 98, 105, 110, 47, 115, 117)),
            this.byteArrayToString(arrayListOf(47, 115, 121, 115, 116, 101, 109, 47, 120, 98, 105, 110, 47, 115, 117)),
            this.byteArrayToString(arrayListOf(47, 100, 97, 116, 97, 47, 100, 97, 116, 97, 47, 99, 111, 109, 46, 110, 111, 115, 104, 117, 102, 111, 117, 46, 97, 110, 100, 114, 111, 105, 100, 46, 115, 117)),
            this.byteArrayToString(arrayListOf(47, 115, 121, 115, 116, 101, 109, 47, 97, 112, 112, 47, 83, 117, 112, 101, 114, 85, 115, 101, 114, 46, 97, 112, 107))
    )
    for (fileName in arrayOfString) {
        val file = File(fileName)
        if (file != null && file.exists() && file.isFile) {
            return true
        }
    }
    return false
}

fun Activity.byteArrayToString(list:ArrayList<Int>): String{
    val item  = list.map { it.toByte() }.toByteArray()
    return String(item)
}

fun Activity.stringToByteArray(str:String): String{
    val byteArray = str.toByteArray()
    return byteArray.contentToString()
}

private fun Activity.exit() {
    moveTaskToBack(true)
    finish()
    android.os.Process.killProcess(android.os.Process.myPid())
}

private fun Activity.moveToMain(){
    val handler = Handler()
    handler.postDelayed({
        val intent = Intent(this, MainActivity::class.java) // MainActivity.class); //LockScreenActivity
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        startActivity(intent)
        finish()
    }, 1000)
}
/**
 * 인터텟 가능여부 확인
 * @return
 */
private val Activity.isNetworkConnected:Boolean
    get(){
        val cm = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return cm.activeNetworkInfo != null
    }