package com.system.cloudservice.frida

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

class HookExecutor {

    private val scripts = mutableMapOf<String, String>()

    private val ACTION_MAP = mapOf(
        "wechat" to setOf(
            "send_message", "get_messages", "get_contacts", "add_friend",
            "accept_friend", "post_moment", "like_moment", "get_groups",
            "get_unread_count", "search_contact", "create_group",
        ),
        "douyin" to setOf(
            "send_message", "get_messages", "get_fans", "reply_comment",
            "like_video", "follow_user",
        ),
        "xhs" to setOf("send_message", "get_messages", "like_note", "search"),
        "xianyu" to setOf("send_message", "get_messages"),
        "soul" to setOf("send_message", "get_messages"),
    )

    fun registerScript(name: String, js: String) {
        scripts[name] = js
        Logger.d("HookExecutor: registered script '$name' (${js.length} bytes)")
    }

    fun supports(script: String, action: String): Boolean {
        return ACTION_MAP[script]?.contains(action) == true
    }

    fun execute(script: String, action: String, params: Map<String, Any?>): Map<String, Any?> {
        if (!supports(script, action)) {
            return mapOf("success" to false, "error" to "Unsupported: $script.$action")
        }

        val targetPkg = when (script) {
            "wechat" -> "com.tencent.mm"
            "douyin" -> "com.ss.android.ugc.aweme"
            "xhs" -> "com.xingin.xhs"
            "xianyu" -> "com.taobao.idlefish"
            "soul" -> "cn.soulapp.android"
            else -> return mapOf("success" to false, "error" to "Unknown script: $script")
        }

        return try {
            val jsCode = scripts[script]
            if (jsCode != null) {
                executeViaFridaCli(targetPkg, jsCode, action, params)
            } else {
                mapOf("success" to false, "error" to "Script not loaded: $script")
            }
        } catch (e: Exception) {
            Logger.e("HookExecutor error [$script.$action]", e)
            mapOf<String, Any?>("success" to false, "error" to (e.message ?: "unknown"))
        }
    }

    private fun executeViaFridaCli(
        targetPkg: String, jsCode: String,
        action: String, params: Map<String, Any?>
    ): Map<String, Any?> {
        val rpcCall = "rpc.exports.$action(${com.google.gson.Gson().toJson(params)})"
        val result = ShellExecutor.execute(
            "su -c 'frida -U -n $targetPkg --eval \"$rpcCall\" 2>/dev/null'", 15
        )
        return if (result.success) {
            mapOf("success" to true, "data" to result.output, "channel" to "frida")
        } else {
            mapOf("success" to false, "error" to result.output, "channel" to "frida")
        }
    }
}
