package com.optix.android.tools.utility

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 java.security.SecureRandom

class PasswordGeneratorTool : BaseTool() {

    override val metadata = ToolMetadata(
        name = "password_generator",
        displayName = "Password Generator",
        description = "Generate cryptographically secure random passwords",
        category = ToolCategory.PAYLOADS_UTILITIES,
        requiresNetwork = false,
        parameters = listOf(
            ToolParam("length", ParamType.INT, "Password length", required = false, defaultValue = "20"),
            ToolParam("count", ParamType.INT, "Number of passwords", required = false, defaultValue = "5"),
            ToolParam("include_symbols", ParamType.BOOLEAN, "Include symbols", required = false, defaultValue = "true"),
            ToolParam("include_numbers", ParamType.BOOLEAN, "Include numbers", required = false, defaultValue = "true"),
        ),
    )

    override suspend fun execute(params: Map<String, Any>, emit: suspend (ToolEvent) -> Unit) {
        val length = paramInt(params, "length", 20).coerceIn(8, 128)
        val count = paramInt(params, "count", 5).coerceIn(1, 50)
        val includeSymbols = paramBool(params, "include_symbols", true)
        val includeNumbers = paramBool(params, "include_numbers", true)

        val charset = buildString {
            append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
            if (includeNumbers) append("0123456789")
            if (includeSymbols) append("!@#\$%^&*()-_=+[]{}|;:,.<>?")
        }

        val rng = SecureRandom()
        emit(ToolEvent.Log("Generating $count passwords (length=$length)"))

        repeat(count) {
            val password = (1..length).map { charset[rng.nextInt(charset.length)] }.joinToString("")
            emit(ToolEvent.Result(OsintResult("Password", password, "SecureRandom")))
            emit(ToolEvent.Log("  $password"))
        }

        emit(ToolEvent.ChainSuggestion("brute_force", mapOf("target" to "127.0.0.1", "protocol" to "ssh", "username" to "admin")))
        emit(ToolEvent.Done)
    }
}
