package com.optix.android.tools.web

import com.optix.android.domain.model.OsintResult
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.parser.HttpHeaderParser
import com.optix.android.tools.registry.BaseTool
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request

class HttpInspectorTool(private val client: OkHttpClient) : BaseTool() {

    override val metadata = ToolMetadata(
        name = "http_inspector",
        displayName = "HTTP Inspector",
        description = "HTTP header analysis, security header audit, and redirect chain",
        category = ToolCategory.DNS_WEB,
        parameters = listOf(
            ToolParam("url", ParamType.STRING, "Target URL"),
            ToolParam("follow_redirects", ParamType.BOOLEAN, "Follow redirect chain", required = false, defaultValue = "true"),
        ),
    )

    override suspend fun execute(params: Map<String, Any>, emit: suspend (ToolEvent) -> Unit) {
        val url = paramRequired(params, "url")
        emit(ToolEvent.Log("Inspecting $url"))

        withContext(Dispatchers.IO) {
            val request = Request.Builder().url(url).head().build()
            runCatching {
                client.newCall(request).execute().use { response ->
                    emit(ToolEvent.Log("Status: ${response.code} ${response.message}"))
                    response.headers.forEach { (name, value) ->
                        emit(ToolEvent.Result(OsintResult(name, value, "HTTP Header")))
                    }
                    // Structured security-header audit -> typed VulnerabilityFinding
                    // objects so the UI can render severity chips and filter.
                    val headerPairs = response.headers.map { it.first to it.second }
                    HttpHeaderParser.auditSecurityHeaders(headerPairs, url).forEach { finding ->
                        emit(ToolEvent.Result(finding))
                        emit(ToolEvent.Log("  [${finding.severity}] ${finding.title}"))
                    }
                    if (response.code in 200..399) {
                        emit(ToolEvent.ChainSuggestion("sqli_tester", mapOf("url" to url)))
                    }
                }
            }.onFailure { emit(ToolEvent.Error("Request failed: ${it.message}")) }
        }

        emit(ToolEvent.Done)
    }

    companion object {
        val SECURITY_HEADERS = listOf(
            "Strict-Transport-Security", "Content-Security-Policy",
            "X-Frame-Options", "X-Content-Type-Options",
            "Referrer-Policy", "Permissions-Policy",
        )
    }
}
