"""
OSINT Search Tool - Dark web search via Tor proxy

Provides dark web search capabilities across multiple search engines.
"""

from typing import Any, Optional

from groknroll.osint.dark_web_search import DarkWebSearch
from groknroll.osint.tor_manager import TorManager
from groknroll.tools.base_tool import BaseTool


class OsintSearchTool(BaseTool):
    """
    Dark web search tool using Tor proxy.

    Searches across 16 dark web search engines to find relevant .onion sites.

    Usage:
        tool = OsintSearchTool()
        results = await tool.execute(query="ransomware", limit=50)
    """

    def __init__(
        self,
        tor_host: str = "127.0.0.1",
        tor_port: int = 9050,
        max_workers: int = 5,
    ):
        """
        Initialize OSINT search tool.

        Args:
            tor_host: Tor SOCKS5 proxy host
            tor_port: Tor SOCKS5 proxy port
            max_workers: Maximum concurrent search threads
        """
        self.tor_host = tor_host
        self.tor_port = tor_port
        self.max_workers = max_workers
        self._tor_manager: Optional[TorManager] = None
        self._search: Optional[DarkWebSearch] = None

    @property
    def name(self) -> str:
        return "osint_search"

    @property
    def description(self) -> str:
        return "Search dark web engines for intelligence via Tor proxy"

    @property
    def tor_manager(self) -> TorManager:
        """Get or create TorManager."""
        if self._tor_manager is None:
            self._tor_manager = TorManager(self.tor_host, self.tor_port)
        return self._tor_manager

    @property
    def search(self) -> DarkWebSearch:
        """Get or create DarkWebSearch."""
        if self._search is None:
            self._search = DarkWebSearch(self.tor_manager, self.max_workers)
        return self._search

    async def execute(
        self,
        query: str,
        engines: Optional[list[str]] = None,
        limit: int = 50,
        **kwargs,
    ) -> list[dict]:
        """
        Execute dark web search.

        Args:
            query: Search query string
            engines: Optional list of specific engines to use
            limit: Maximum results to return

        Returns:
            List of search result dictionaries with url, title, source_engine

        Raises:
            ConnectionError: If Tor proxy is not available
        """
        # Validate Tor connectivity
        if not self.tor_manager.check_connection():
            raise ConnectionError(
                f"Tor proxy not available at {self.tor_host}:{self.tor_port}. "
                "Ensure Tor daemon is running."
            )

        # Perform search
        results = self.search.search(query, engines=engines, limit=limit)

        # Convert to dictionaries
        return [result.to_dict() for result in results]

    def validate_params(self, **kwargs) -> dict[str, Any]:
        """Validate search parameters."""
        if "query" not in kwargs or not kwargs["query"]:
            raise ValueError("query parameter is required")

        limit = kwargs.get("limit", 50)
        if not isinstance(limit, int) or limit < 1 or limit > 500:
            raise ValueError("limit must be an integer between 1 and 500")

        engines = kwargs.get("engines")
        if engines is not None:
            if not isinstance(engines, list):
                raise ValueError("engines must be a list of engine names")
            available = self.search.get_available_engines()
            for engine in engines:
                if engine not in available:
                    raise ValueError(f"Unknown engine: {engine}. Available: {available}")

        return kwargs

    def get_available_engines(self) -> list[str]:
        """Get list of available search engine names."""
        return self.search.get_available_engines()

    def check_status(self) -> dict[str, Any]:
        """Check tool status."""
        connected = self.tor_manager.check_connection()
        return {
            "tor_connected": connected,
            "tor_proxy": f"{self.tor_host}:{self.tor_port}",
            "engines_available": len(self.search.engines),
        }
