"""
OSINT Scrape Tool - Content scraping via Tor proxy

Provides content scraping capabilities for dark web and clearweb URLs.
"""

from typing import Any, Optional

from groknroll.osint.content_scraper import ContentScraper
from groknroll.osint.tor_manager import TorManager
from groknroll.tools.base_tool import BaseTool


class OsintScrapeTool(BaseTool):
    """
    Content scraping tool using Tor proxy for .onion sites.

    Scrapes and extracts text content from URLs with automatic
    script/style removal and text normalization.

    Usage:
        tool = OsintScrapeTool()
        results = await tool.execute(urls=["http://example.onion/page"])
    """

    def __init__(
        self,
        tor_host: str = "127.0.0.1",
        tor_port: int = 9050,
        max_workers: int = 5,
        timeout: int = 45,
        max_content_length: int = 5000,
    ):
        """
        Initialize OSINT scrape tool.

        Args:
            tor_host: Tor SOCKS5 proxy host
            tor_port: Tor SOCKS5 proxy port
            max_workers: Maximum concurrent scraping threads
            timeout: Request timeout in seconds
            max_content_length: Maximum content characters to keep
        """
        self.tor_host = tor_host
        self.tor_port = tor_port
        self.max_workers = max_workers
        self.timeout = timeout
        self.max_content_length = max_content_length
        self._tor_manager: Optional[TorManager] = None
        self._scraper: Optional[ContentScraper] = None

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

    @property
    def description(self) -> str:
        return "Scrape content from dark web and clearweb URLs 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 scraper(self) -> ContentScraper:
        """Get or create ContentScraper."""
        if self._scraper is None:
            self._scraper = ContentScraper(
                self.tor_manager,
                self.max_workers,
                self.timeout,
                self.max_content_length,
            )
        return self._scraper

    async def execute(
        self,
        urls: list[str],
        timeout: Optional[int] = None,
        **kwargs,
    ) -> list[dict]:
        """
        Scrape content from URLs.

        Args:
            urls: List of URLs to scrape
            timeout: Optional custom timeout per request

        Returns:
            List of scraped content dictionaries with url, title, content, success

        Raises:
            ConnectionError: If Tor proxy is not available (for .onion URLs)
        """
        # Check if any URLs are .onion and validate Tor if needed
        has_onion = any(".onion" in url.lower() for url in urls)
        if has_onion and 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 for .onion URLs."
            )

        # Scrape URLs
        results = self.scraper.scrape_batch(urls, timeout=timeout)

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

    async def scrape_single(self, url: str, timeout: Optional[int] = None) -> dict:
        """
        Scrape a single URL.

        Args:
            url: URL to scrape
            timeout: Optional custom timeout

        Returns:
            Scraped content dictionary
        """
        result = self.scraper.scrape(url, timeout=timeout)
        return result.to_dict()

    def validate_params(self, **kwargs) -> dict[str, Any]:
        """Validate scrape parameters."""
        urls = kwargs.get("urls")
        if urls is None:
            raise ValueError("urls parameter is required")

        if not isinstance(urls, list):
            raise ValueError("urls must be a list")

        if not urls:
            raise ValueError("urls list cannot be empty")

        if len(urls) > 100:
            raise ValueError("Maximum 100 URLs per request")

        for url in urls:
            if not isinstance(url, str):
                raise ValueError("All URLs must be strings")
            if not url.startswith(("http://", "https://")):
                raise ValueError(f"Invalid URL scheme: {url}")

        timeout = kwargs.get("timeout")
        if timeout is not None:
            if not isinstance(timeout, int) or timeout < 1 or timeout > 300:
                raise ValueError("timeout must be an integer between 1 and 300")

        return kwargs

    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}",
            "timeout": self.timeout,
            "max_content_length": self.max_content_length,
        }
