package com.optix.android.tools.web

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

/** Nikto web server scanner — Termux bridge. */
class NiktoTool : BaseTool() {
    override val metadata = ToolMetadata(
        name = "nikto_termux",
        displayName = "Nikto (Termux)",
        description = "Web server vulnerability scanner — checks 6700+ dangerous files and misconfigurations",
        category = ToolCategory.DNS_WEB,
        requiresRoot = false,
        parameters = listOf(
            ToolParam("target", ParamType.STRING, "Target URL or IP (e.g. https://example.com or 192.168.1.1)"),
            ToolParam("port", ParamType.INT, "Port number", required = false, defaultValue = "80"),
            ToolParam("ssl", ParamType.BOOLEAN, "Use SSL/HTTPS", required = false, defaultValue = "false"),
            ToolParam("tuning", ParamType.STRING, "Tuning options (1-9, x=all)", required = false, defaultValue = "x"),
        ),
    )

    override suspend fun execute(params: Map<String, Any>, emit: suspend (ToolEvent) -> Unit) {
        val target = paramRequired(params, "target")
        val port = paramInt(params, "port", 80)
        val ssl = paramBool(params, "ssl", false)
        val tuning = param(params, "tuning") ?: "x"

        val args = mutableListOf("-host", target, "-port", port.toString(), "-Tuning", tuning, "-nointeractive")
        if (ssl) args.add("-ssl")

        shellExecutor?.executeTermuxAsRoot("nikto", args, "nikto", emit)
        emit(ToolEvent.ChainSuggestion("sqli_tester", mapOf("url" to target)))
        emit(ToolEvent.Done)
    }
}

/** SQLMap — automated SQL injection exploitation via Termux. */
class SqlmapTool : BaseTool() {
    override val metadata = ToolMetadata(
        name = "sqlmap_termux",
        displayName = "SQLMap (Termux)",
        description = "Automated SQL injection detection and exploitation — far more powerful than built-in SQLi tester",
        category = ToolCategory.DNS_WEB,
        requiresRoot = false,
        parameters = listOf(
            ToolParam("url", ParamType.STRING, "Target URL with parameter (e.g. http://site.com/page?id=1)"),
            ToolParam("level", ParamType.ENUM, "Test level (1=basic, 5=extensive)", required = false, defaultValue = "2",
                enumValues = listOf("1", "2", "3", "4", "5")),
            ToolParam("risk", ParamType.ENUM, "Risk level (1=safe, 3=aggressive)", required = false, defaultValue = "1",
                enumValues = listOf("1", "2", "3")),
            ToolParam("dbms", ParamType.STRING, "Force DBMS type (mysql, postgresql, mssql)", required = false, defaultValue = ""),
            ToolParam("dump", ParamType.BOOLEAN, "Dump database contents if vulnerable", required = false, defaultValue = "false"),
        ),
    )

    override suspend fun execute(params: Map<String, Any>, emit: suspend (ToolEvent) -> Unit) {
        val url = paramRequired(params, "url")
        val level = param(params, "level") ?: "2"
        val risk = param(params, "risk") ?: "1"
        val dbms = param(params, "dbms") ?: ""
        val dump = paramBool(params, "dump", false)

        val args = mutableListOf("-u", url, "--level=$level", "--risk=$risk", "--batch", "--output-dir=/sdcard/Optix/sqlmap")
        if (dbms.isNotEmpty()) args.add("--dbms=$dbms")
        if (dump) args.add("--dump")

        shellExecutor?.executeTermuxAsRoot("sqlmap", args, "sqlmap", emit)
        emit(ToolEvent.ChainSuggestion("nuclei_termux", mapOf("target" to url)))
        emit(ToolEvent.Done)
    }
}
