package com.optix.android.tools.network

import com.optix.android.domain.model.ParamType
import com.optix.android.domain.model.ToolCategory
import com.optix.android.domain.model.ToolEvent
import com.optix.android.domain.model.ToolMetadata
import com.optix.android.domain.model.ToolParam
import com.optix.android.tools.registry.BaseTool
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext

/** Packet sniffer — requires root binaries. Executes tcpdump. */
class PacketSnifferTool : BaseTool() {

    override val metadata = ToolMetadata(
        name = "packet_sniffer",
        displayName = "Packet Sniffer",
        description = "Capture and analyse network packets (requires root)",
        category = ToolCategory.NETWORK_SCANNING,
        requiresRoot = true,
        requiredPackages = listOf("tcpdump"),
        parameters = listOf(
            ToolParam("interface", ParamType.STRING, "Network interface (e.g. wlan0)", required = false, defaultValue = "wlan0"),
            ToolParam("filter", ParamType.STRING, "BPF filter expression", required = false, defaultValue = ""),
            ToolParam("count", ParamType.INT, "Packet count limit", required = false, defaultValue = "100"),
        ),
    )

    override suspend fun execute(params: Map<String, Any>, emit: suspend (ToolEvent) -> Unit) {
        val iface = param(params, "interface") ?: "wlan0"
        val filter = param(params, "filter") ?: ""
        val count = paramInt(params, "count", 100)

        emit(ToolEvent.Log("Running root packet capture on $iface..."))

        withContext(Dispatchers.IO) {
            try {
                val args = mutableListOf("-i", iface, "-c", count.toString())
                if (filter.isNotBlank()) args.addAll(filter.split("\\s+".toRegex()))
                shellExecutor?.executeTermuxAsRoot("tcpdump", args, "tcpdump", emit)
            } catch (e: Exception) {
                emit(ToolEvent.Error("Failed to initiate root shell: ${e.message}"))
            }
        }
        emit(ToolEvent.ChainSuggestion("network_topology", mapOf("target" to "8.8.8.8")))
        emit(ToolEvent.Done)
    }
}
