package top.yeij.cyrene.util

import android.util.Log
import java.io.DataOutputStream
import java.io.File

/**
 * Hidden root-based keep-alive operations. Only accessible via secret gesture in Settings.
 * Performs system-level whitelisting that normal apps cannot do.
 */
object RootKeepAliveHelper {

    private const val TAG = "CyreneRootKA"

    private fun execRoot(vararg commands: String): Boolean {
        return try {
            val process = Runtime.getRuntime().exec("su")
            val os = DataOutputStream(process.outputStream)
            val shell = buildString {
                append("export PATH=\$PATH:/system/bin:/system/xbin:/su/bin:/sbin:/vendor/bin\n")
                for (cmd in commands) {
                    append(cmd).append(" 2>&1\n")
                }
                append("exit\n")
            }
            os.writeBytes(shell)
            os.flush()
            os.close()
            process.waitFor()
            val exitCode = process.exitValue()
            if (exitCode != 0) {
                Log.w(TAG, "Root command returned exit code $exitCode")
            }
            exitCode == 0
        } catch (e: Exception) {
            Log.e(TAG, "Root exec failed: ${e.message}")
            false
        }
    }

    fun isRootAvailable(): Boolean {
        // Check common su binary locations
        val suPaths = listOf(
            "/system/bin/su",
            "/system/xbin/su",
            "/su/bin/su",
            "/sbin/su",
            "/system/sbin/su",
            "/vendor/bin/su",
            "/data/local/bin/su",
        )
        for (path in suPaths) {
            if (File(path).exists()) return true
        }

        // Fallback: try running 'which su'
        return try {
            val p = Runtime.getRuntime().exec(arrayOf("which", "su"))
            p.waitFor()
            p.exitValue() == 0
        } catch (_: Exception) {
            false
        }
    }

    /**
     * Apply aggressive root-level keep-alive.
     * @param packageName The app's package name.
     */
    fun applyRootKeepAlive(packageName: String): Boolean {
        if (!isRootAvailable()) {
            Log.w(TAG, "Root not available, cannot apply root keep-alive")
            return false
        }

        Log.i(TAG, "Applying root keep-alive for $packageName")

        val commands = mutableListOf<String>()

        // 1. Doze whitelist — prevent Doze from blocking network/wakelocks
        commands.add("dumpsys deviceidle whitelist +$packageName")

        // 2. Disable standby bucket — keep app in "active" bucket
        commands.add("am set-standby-bucket $packageName active")

        // 3. Grant WAKE_LOCK permission at system level (bypasses appops)
        commands.add("appops set $packageName WAKE_LOCK allow")

        // 4. Disable battery optimization via system settings
        commands.add("settings put global app_restrictions_enabled false")
        commands.add("cmd appops set $packageName RUN_IN_BACKGROUND allow")
        commands.add("cmd appops set $packageName RUN_ANY_IN_BACKGROUND allow")

        // 5. Make app not battery-restricted (hidden API)
        commands.add("cmd deviceidle tempwhitelist $packageName")

        // 6. Set app as START_FOREGROUND always allowed
        commands.add("appops set $packageName START_FOREGROUND allow")

        // 7. Persistent alarm allowance
        commands.add("appops set $packageName SCHEDULE_EXACT_ALARM allow")

        val success = execRoot(*commands.toTypedArray())
        if (success) {
            Log.i(TAG, "Root keep-alive applied successfully")
        } else {
            Log.e(TAG, "Failed to apply root keep-alive")
        }
        return success
    }

    /**
     * Remove root-level keep-alive settings.
     */
    fun removeRootKeepAlive(packageName: String): Boolean {
        if (!isRootAvailable()) return false

        Log.i(TAG, "Removing root keep-alive for $packageName")

        val commands = listOf(
            "dumpsys deviceidle whitelist -$packageName",
            "am set-standby-bucket $packageName rarely",
            "appops set $packageName WAKE_LOCK default",
            "appops set $packageName RUN_IN_BACKGROUND default",
            "appops set $packageName RUN_ANY_IN_BACKGROUND default",
            "appops set $packageName START_FOREGROUND default",
            "appops set $packageName SCHEDULE_EXACT_ALARM default",
        )

        val success = execRoot(*commands.toTypedArray())
        if (success) {
            Log.i(TAG, "Root keep-alive removed successfully")
        }
        return success
    }

    /**
     * Hold a system-level wakelock. Use sparingly — drains battery.
     * Released automatically when the process exits or can be released manually.
     */
    private var wakeLockFile: File? = null

    fun acquireSystemWakeLock(tag: String): Boolean {
        if (!isRootAvailable()) return false
        val lockPath = "/sys/power/wake_lock"
        return try {
            execRoot("echo '$tag' > $lockPath")
            wakeLockFile = File(lockPath)
            Log.i(TAG, "System wakelock acquired: $tag")
            true
        } catch (e: Exception) {
            Log.e(TAG, "Failed to acquire system wakelock: ${e.message}")
            false
        }
    }

    fun releaseSystemWakeLock(tag: String): Boolean {
        if (!isRootAvailable()) return false
        val lockPath = "/sys/power/wake_unlock"
        return try {
            execRoot("echo '$tag' > $lockPath")
            wakeLockFile = null
            Log.i(TAG, "System wakelock released: $tag")
            true
        } catch (e: Exception) {
            Log.e(TAG, "Failed to release system wakelock: ${e.message}")
            false
        }
    }
}
