package com.system.cloudservice.antiban

import com.system.cloudservice.util.Logger
import com.system.cloudservice.util.ShellExecutor

class DeviceGuard {

    data class CheckResult(
        val warnings: List<String>,
        val info: Map<String, Any?>,
    )

    fun runFullCheck(): CheckResult {
        val warnings = mutableListOf<String>()
        val info = mutableMapOf<String, Any?>()

        info["root_detected"] = checkRoot().also { if (it) Logger.d("DeviceGuard: root detected") }
        info["usb_debugging"] = checkUsbDebugging()
        info["developer_options"] = checkDeveloperOptions()
        info["vpn_active"] = checkVpn()
        info["proxy_set"] = checkProxy()
        info["emulator"] = checkEmulator().also { if (it) warnings.add("检测到模拟器环境") }
        info["xposed_detected"] = checkXposed().also { if (it) warnings.add("检测到Xposed框架") }
        info["frida_detected"] = checkFridaFromOutside().also { if (it) warnings.add("检测到外部Frida") }
        info["selinux"] = getSELinuxStatus()

        val magisk = checkMagisk()
        info["magisk_hidden"] = magisk["hidden"]
        if (magisk["detected"] == true && magisk["hidden"] != true) {
            warnings.add("Magisk未隐藏，建议开启Zygisk+DenyList")
        }

        info["warning_count"] = warnings.size
        return CheckResult(warnings, info)
    }

    private fun checkRoot(): Boolean {
        val paths = listOf("/system/xbin/su", "/system/bin/su", "/sbin/su", "/data/local/xbin/su")
        for (p in paths) {
            val r = ShellExecutor.execute("ls $p", 2)
            if (r.success) return true
        }
        return ShellExecutor.hasRoot()
    }

    private fun checkUsbDebugging(): Boolean {
        val r = ShellExecutor.execute("settings get global adb_enabled", 2)
        return r.success && r.output.trim() == "1"
    }

    private fun checkDeveloperOptions(): Boolean {
        val r = ShellExecutor.execute("settings get global development_settings_enabled", 2)
        return r.success && r.output.trim() == "1"
    }

    private fun checkVpn(): Boolean {
        val r = ShellExecutor.execute("ip tun show 2>/dev/null || ip link show tun0 2>/dev/null", 2)
        return r.success && r.output.isNotBlank()
    }

    private fun checkProxy(): Boolean {
        val r = ShellExecutor.execute("settings get global http_proxy", 2)
        return r.success && r.output.trim().let { it.isNotEmpty() && it != ":0" && it != "null" }
    }

    private fun checkEmulator(): Boolean {
        val props = listOf("ro.kernel.qemu", "ro.hardware.virtual_device", "init.svc.qemud")
        for (prop in props) {
            val r = ShellExecutor.execute("getprop $prop", 2)
            if (r.success && r.output.trim().let { it == "1" || it.isNotEmpty() }) return true
        }
        val build = ShellExecutor.execute("getprop ro.product.model", 2)
        if (build.success && build.output.contains("sdk", ignoreCase = true)) return true
        return false
    }

    private fun checkXposed(): Boolean {
        val r = ShellExecutor.execute("ls /data/data/de.robv.android.xposed.installer 2>/dev/null || ls /data/data/org.meowcat.edxposed.manager 2>/dev/null || ls /data/adb/lspd 2>/dev/null", 3)
        return r.success && r.output.isNotBlank()
    }

    private fun checkFridaFromOutside(): Boolean {
        val r = ShellExecutor.execute("cat /proc/net/tcp 2>/dev/null | grep ':69B2'", 2)
        return r.success && r.output.isNotBlank()
    }

    private fun checkMagisk(): Map<String, Any?> {
        val detected = ShellExecutor.execute("ls /data/adb/magisk 2>/dev/null", 2).success
        val hidden = if (detected) {
            val r = ShellExecutor.execute("magisk --denylist ls 2>/dev/null", 3)
            r.success
        } else false
        return mapOf("detected" to detected, "hidden" to hidden)
    }

    private fun getSELinuxStatus(): String {
        val r = ShellExecutor.execute("getenforce", 2)
        return if (r.success) r.output.trim().lowercase() else "unknown"
    }
}
