package com.secspace.lib.common.function

import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Build.VERSION_CODES
import android.util.Log
import com.secspace.lib.common.env.Packages.PkgSecSpace
import com.secspace.lib.common.utils.*
import com.secspace.lib.common.utils.Package.ComponentNames.COMPONENT_UPDATE_SYSTEM
import com.secspace.lib.common.utils.Package.ComponentNames.EnterprisePrivacySettingsActivity
import com.secspace.mdmengine.api.manager.MdmFactoryManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.*

object SwitchInMdm: ISwitch() {
    private var context: Context? = null
    private val TAG = "SwitchInMdm"
    override suspend fun init(context: Context) {
        this.context = context
        if(MdmFactoryManager.getInstance().deviceApplicationManager == null){
            return
        }
        Prefs.setInSpace(context, true)
        MdmUtils.setDefaultLauncher(context)

        val mdmFactoryManager = DpmHelper.getInstance(context).getmMdmFactoryManager()
        mdmFactoryManager.deviceApplicationManager.addDisabledDeactivateMdmPackages(getPersistentList(context))
        mdmFactoryManager.deviceApplicationManager.addDisallowedUninstallPackages(getPersistentList(context))
        mdmFactoryManager.deviceApplicationManager.addPersistentApp(getPersistentList(context))
        val arrayList = ArrayList<String>()
        arrayList.add(context.packageName)
        mdmFactoryManager.deviceSettingsManager.superWhiteListForHwSystemManger = arrayList
        mdmFactoryManager.deviceRestrictionManager.turnOnGPS(true)
        MdmFactoryManager.getInstance().deviceApplicationManager.setApplicationEnabledSetting("com.huawei.powergenie", PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 1)

        addDisallowedRunningApp(context)
        clearProcesses()
        clearTasks(context)
        killBackgroundApplication()
        isCoverInstall()

        hiddenPkgIcon(context)
    }

    private fun hiddenPkgIcon(context: Context){
        if (android.os.Build.VERSION.SDK_INT >= VERSION_CODES.P)
            Settings.hiddenPkgIcon(context)
    }

    private fun clearTasks(context: Context) {
        try {
            val recentTasks = ReflectAmsUtil.getRecentTasks(context, 1000, 0)
            for (recentTask in recentTasks) {
                val intent = recentTask.baseIntent ?: continue
                var packageName = intent.`package`
                if (packageName == null) {
                    val componentName = intent.component ?: continue
                    packageName = componentName.packageName
                }
                if (packageName == context.packageName) {
                    continue
                }
                ReflectAmsUtil.removeTask(context, recentTask.affiliatedTaskId)
                Log.i(TAG, String.format("clear task: pkg(%s) label(%s)"
                        , packageName
                        , if (recentTask.taskDescription == null) recentTask.description else recentTask.taskDescription.label))
            }
        } catch (e: Exception) {
            Log.i(TAG, "clearTasks Exception: $e")
        }
    }

    suspend fun addDisallowedRunningApp(context: Context) {
        withContext(Dispatchers.IO) {
            val mdmFactoryManager = DpmHelper.getInstance(context).getmMdmFactoryManager()
            val pkgsList = Prefs.getUserShowAppPkgs(context)
            val resolveInfos: List<ResolveInfo> = context.packageManager.queryIntentActivities(Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER), 0)
            val items = ArrayList<String>()
//
            resolveInfos.filter {
                val apiInfo = context.packageManager.getApplicationInfo(it.activityInfo.packageName, 0)
                apiInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0
            }.forEach {
                if (it.activityInfo.packageName != context.packageName)
                    items.add(it.activityInfo.packageName)
            }
            Log.e(TAG, "ALL:${items}")
            val oldApps = mdmFactoryManager.deviceApplicationManager.disallowedRunningApp
            mdmFactoryManager.deviceApplicationManager.removeDisallowedRunningApp(oldApps)
            items.filter {
                !pkgsList.contains(it)
            }.let {
                Log.e(TAG, "after:${it}")
                mdmFactoryManager.deviceApplicationManager.addDisallowedRunningApp(it)
            }
        }
    }

    private fun isCoverInstall() {
        val mdmFactoryManager = MdmFactoryManager.getInstance()
        mdmFactoryManager.deviceRestrictionManager.isAdbDisabled = false
        mdmFactoryManager.deviceRestrictionManager.isUSBOtgDisabled = false
        mdmFactoryManager.deviceRestrictionManager.isUSBDataDisabled = false
        mdmFactoryManager.deviceRestrictionManager.isExternalStorageDisabled = false

        mdmFactoryManager.deviceSettingsManager.isRestoreFactoryDisabled = false
        mdmFactoryManager.deviceSettingsManager.isSystemUpdateDisabled = false

        DisableCompat.enableComponent(context, COMPONENT_UPDATE_SYSTEM)
        DisableCompat.enableComponent(context, EnterprisePrivacySettingsActivity)
    }



    private fun clearProcesses() {
        val dam = MdmFactoryManager.getInstance().deviceApplicationManager
        //clear task
        val runningTasks = dam.getRunningTasks(1000)
        if (runningTasks != null) {
            for (task in runningTasks) {
                val pkg = task.baseActivity.packageName
                if (pkg == context?.packageName || pkg == PkgSecSpace.PACKAGENAME_MIDDLEWARE || pkg == "com.android.systemui") {
                    continue
                }
                dam.removeTask(task.id)
                Log.d(TAG, "remove task " + task.baseActivity.packageName)
            }
        }
        //clear processes
        val runningAppProcesses = dam.runningAppProcesses
        val packages = getAllPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES)
        if (runningAppProcesses != null) {
            for (processInfo in runningAppProcesses) {
                val processName = processInfo.processName
                if (!packages.contains(processName)) {
                    continue
                }
                if (processName == PkgSecSpace.PACKAGENAME_MIDDLEWARE || context?.packageName == processName || processName == "com.huawei.powergenie") {
                    continue
                }
                dam.killApplicationProcess(processName)
                dam.forceStopPackage(processName)
                Log.d(TAG, "kill $processName")
            }
        }
    }

    private fun getAllPackages(flags: Int): List<String> {
        val packageInfos = getAllPackageInfo(flags)
        val list: MutableList<String> = ArrayList()
        for (i in packageInfos.indices) {
            list.add(packageInfos[i].packageName)
        }
        return list
    }

    private fun getAllPackageInfo(flags: Int): List<PackageInfo> {
        return context!!.packageManager.getInstalledPackages(flags)
    }


    private fun killBackgroundApplication() {
        val packageManager: PackageManager? = context?.packageManager
        val mainIntent = Intent(Intent.ACTION_MAIN, null)
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER)
        val apps = packageManager?.queryIntentActivities(mainIntent, 0)
        for (i in apps?.indices!!) {
            val name = apps[i].activityInfo.packageName
            Log.i(TAG, "killBackgroundApplication: $name")
            if (context?.packageName?.let { name.contains(it) }!! || name == PkgSecSpace.PACKAGENAME_MIDDLEWARE || name == context!!.packageName) {
                continue
            }
            MdmFactoryManager.getInstance().deviceApplicationManager.forceStopPackage(name)
        }
    }
}