#!/usr/bin/env python3

"""
BRS-XSS Fuzz Command

Command for WAF fuzzing testing.

Company: EasyProTech LLC (www.easypro.tech)
Dev: Brabus
Created: Thu 31 Jul 00:17:37 MSK 2025
Telegram: https://t.me/EasyProTech
"""

from typing import Optional

import typer
from rich.console import Console

from brsxss import _


def fuzz_command(
    url: str = typer.Argument(
        ...,
        help="URLs for fuzzing testing",
        metavar="URLs"
    ),
    threads: int = typer.Option(
        5,
        "--threads", "-t",
        help=_("cli.option_threads"),
        min=1,
        max=20
    ),
    delay: float = typer.Option(
        0.5,
        "--delay",
        help="Delay between requests (seconds)",
        min=0.0,
        max=10.0
    ),
    output: Optional[str] = typer.Option(
        None,
        "--output", "-o", 
        help=_("cli.option_output"),
        metavar="FILE"
    ),
):
    """Run fuzzing testing for WAF detection"""
    
    console = Console()
    
    console.print("⚡ [bold blue]" + _("Fuzzing mode") + "[/bold blue]")
    console.print(_("Target: {url}").format(url=url))
    console.print(_("Threads: {threads}").format(threads=threads))
    console.print(_("Delay: {delay}s").format(delay=delay))
    
    try:
        from brsxss.waf.detector import WAFDetector
        from brsxss.waf.fingerprinter import WAFFingerprinter
        from brsxss.utils.validators import URLValidator
        from brsxss.utils.logger import Logger
        import time
        import asyncio
        
        logger = Logger("cli.fuzz")
        
        # Validate URL
        validation_result = URLValidator.validate_url(url)
        if not validation_result.valid:
            console.print(f"[red]Invalid URL: {url}[/red]")
            raise typer.Exit(1)
        
        normalized_url = validation_result.normalized_value or url
        
        # Initialize WAF components
        console.print("Starting WAF fuzzing...")
        waf_detector = WAFDetector()
        waf_fingerprinter = WAFFingerprinter()
        
        start_time = time.time()
        
        # Run WAF detection
        console.print("Detecting WAF...")
        detected_wafs = asyncio.run(waf_detector.detect_waf(normalized_url))
        
        # Run WAF fingerprinting
        console.print("🔬 " + _("Fingerprinting WAF..."))
        fingerprint_result = asyncio.run(waf_fingerprinter.fingerprint_waf(normalized_url))
        
        fuzz_duration = time.time() - start_time
        console.print("\nFuzzing completed")
        
        # Results
        stats = {
            _("WAFs detected"): len(detected_wafs),
            _("Fingerprint confidence"): f"{fingerprint_result.confidence:.0%}" if fingerprint_result else "0%",
            _("Fuzzing duration"): f"{fuzz_duration:.1f} sec",
        }
        
        logger.print_stats(stats)
        
        # Show detected WAFs
        if detected_wafs:
            console.print("\nDetected WAFs:")
            for waf in detected_wafs:
                console.print(f"  • {waf.waf_type.value} (confidence: {waf.confidence:.0%})")
        else:
            console.print("\n[green]No WAF detected[/green]")
        
        # Save results if requested
        if output:
            console.print(f"Saving fuzz results: {output}")
            import json
            fuzz_data = {
                "target_url": normalized_url,
                "detected_wafs": [{
                    "type": waf.waf_type.value,
                    "confidence": waf.confidence,
                    "evidence": waf.evidence
                } for waf in detected_wafs],
                "fuzz_duration": fuzz_duration,
                "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
            }
            
            with open(output if output.endswith('.json') else f"{output}.json", 'w') as f:
                json.dump(fuzz_data, f, indent=2)
            console.print("📄 " + _("Fuzz results saved: {filepath}").format(filepath=output))
        
        # Summary
        if detected_wafs:
            console.print("\n[yellow]WAF protection detected - consider evasion techniques[/yellow]")
        else:
            console.print("\n[green]No WAF detected - direct testing possible[/green]")
            
    except KeyboardInterrupt:
        console.print("\nFuzzing interrupted by user")
        raise typer.Exit(130)
        
    except Exception as e:
        logger.error(f"Fuzzing error: {str(e)}")
        raise typer.Exit(1)


# Create typer app for this command
app = typer.Typer()
app.command()(fuzz_command)