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.registry.BaseTool
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import java.util.regex.Pattern

class NativeWhatWebTool(private val client: OkHttpClient) : BaseTool() {
    override val metadata = ToolMetadata(
        name = "native_whatweb",
        displayName = "WhatWeb (Native)",
        description = "Native Web technology fingerprinter — identifies CMS, frameworks, and server software via headers and HTML.",
        category = ToolCategory.DNS_WEB,
        requiresTermux = false,
        requiresRoot = false,
        parameters = listOf(
            ToolParam("url", ParamType.STRING, "Target URL (e.g. https://example.com)"),
        ),
        chainSuggestions = listOf("http_inspector", "native_wpscan", "directory_fuzzer"),
    )

    override suspend fun execute(params: Map<String, Any>, emit: suspend (ToolEvent) -> Unit) {
        var url = paramRequired(params, "url")
        if (!url.startsWith("http://") && !url.startsWith("https://")) {
            url = "http://$url"
        }

        emit(ToolEvent.Log("[WhatWeb] Fingerprinting $url natively..."))

        withContext(Dispatchers.IO) {
            try {
                val request = Request.Builder().url(url).build()
                client.newCall(request).execute().use { response ->
                    val technologies = mutableListOf<String>()

                    // 1. Check Headers
                    response.header("Server")?.let { technologies.add("Server: $it") }
                    response.header("X-Powered-By")?.let { technologies.add("Powered-By: $it") }
                    response.header("X-AspNet-Version")?.let { technologies.add("ASP.NET: $it") }
                    response.header("Via")?.let { technologies.add("Via: $it") }

                    val cookies = response.headers("Set-Cookie")
                    if (cookies.any { it.contains("PHPSESSID", ignoreCase = true) }) technologies.add("PHP")
                    if (cookies.any { it.contains("JSESSIONID", ignoreCase = true) }) technologies.add("Java/JSP")
                    if (cookies.any { it.contains("csrftoken", ignoreCase = true) }) technologies.add("Django")

                    // 2. Check Body
                    val body = response.body?.string() ?: ""
                    
                    if (body.contains("<meta name=\"generator\" content=\"WordPress", ignoreCase = true) ||
                        body.contains("wp-content/themes/", ignoreCase = true)) {
                        technologies.add("CMS: WordPress")
                    }
                    if (body.contains("Joomla!", ignoreCase = true) || body.contains("index.php?option=com_", ignoreCase = true)) {
                        technologies.add("CMS: Joomla")
                    }
                    if (body.contains("Drupal", ignoreCase = true) || body.contains("sites/all/themes", ignoreCase = true)) {
                        technologies.add("CMS: Drupal")
                    }
                    if (body.contains("Ghost", ignoreCase = true)) {
                        technologies.add("CMS: Ghost")
                    }
                    if (body.contains("React", ignoreCase = true) || body.contains("data-reactroot", ignoreCase = true)) {
                        technologies.add("Framework: React")
                    }
                    if (body.contains("ng-app", ignoreCase = true) || body.contains("angular", ignoreCase = true)) {
                        technologies.add("Framework: AngularJS")
                    }
                    if (body.contains("vue", ignoreCase = true) || body.contains("data-v-", ignoreCase = true)) {
                        technologies.add("Framework: Vue.js")
                    }
                    if (body.contains("laravel", ignoreCase = true)) {
                        technologies.add("Framework: Laravel")
                    }
                    
                    // Regex for Title
                    val titleMatcher = Pattern.compile("<title>(.*?)</title>", Pattern.CASE_INSENSITIVE).matcher(body)
                    if (titleMatcher.find()) {
                        val title = titleMatcher.group(1)?.trim() ?: ""
                        emit(ToolEvent.Log("[WhatWeb] Page Title: $title"))
                    }

                    if (technologies.isEmpty()) {
                        emit(ToolEvent.Log("[WhatWeb] No obvious technologies identified."))
                    } else {
                        emit(ToolEvent.Log("[WhatWeb] Discovered Technologies:"))
                        technologies.distinct().forEach { tech ->
                            emit(ToolEvent.Result(OsintResult("Technology", tech, url)))
                            emit(ToolEvent.Log("  - $tech"))
                        }
                    }
                }
            } catch (e: Exception) {
                emit(ToolEvent.Error("Fingerprinting failed: ${e.message}", e))
            }
        }
        emit(ToolEvent.ChainSuggestion("http_inspector", mapOf("url" to url)))
        emit(ToolEvent.Done)
    }
}
