"""
CHRONOS CLI - Cryptographic Scanner Command
"""

import asyncio
from typing import Optional

import typer
from rich.console import Console
from rich.table import Table
from rich.panel import Panel

from chronos.core.analyze.crypto_scanner import (
    CryptoScanner,
    CipherSuiteAnalyzer,
)

app = typer.Typer(name="crypto", help="Cryptographic security scanning")
console = Console()


@app.command("scan")
def scan_host(
    host: str = typer.Argument(..., help="Target hostname or IP address"),
    port: int = typer.Option(443, "--port", "-p", help="Target port"),
    timeout: int = typer.Option(10, "--timeout", "-t", help="Connection timeout in seconds"),
    verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose output"),
):
    """
    Scan a host for SSL/TLS configuration and vulnerabilities.
    
    Example: chronos crypto scan example.com --port 443 --verbose
    """
    console.print(
        Panel(
            f"[bold]CHRONOS Cryptographic Scanner[/bold]\n"
            f"Target: {host}:{port}",
            style="cyan"
        )
    )
    
    scanner = CryptoScanner(timeout=timeout, verbose=verbose)
    
    try:
        # Run async scan
        ssl_info = asyncio.run(scanner.scan_host(host, port))
        
        # Display results
        _display_scan_results(ssl_info)
        
    except Exception as e:
        console.print(f"[red]Error:[/red] {str(e)}", style="bold")
        raise typer.Exit(1)


@app.command("banner")
def grab_banner(
    host: str = typer.Argument(..., help="Target hostname or IP address"),
    port: int = typer.Option(443, "--port", "-p", help="Target port"),
):
    """
    Grab SSL/TLS banner to detect server information.
    
    Example: chronos crypto banner example.com
    """
    scanner = CryptoScanner()
    banner = scanner.scan_ssl_banner(host, port)
    
    table = Table(title="SSL/TLS Banner Information")
    table.add_column("Property", style="cyan")
    table.add_column("Value", style="green")
    
    for key, value in banner.items():
        table.add_row(key, str(value))
    
    console.print(table)


@app.command("pqc-detect")
def detect_pqc(
    config_path: str = typer.Argument(
        ".",
        help="Path to configuration file or directory"
    ),
    verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose output"),
):
    """
    Detect NIST PQC algorithm references in configuration files.
    
    Example: chronos crypto pqc-detect ./config --verbose
    """
    scanner = CryptoScanner(verbose=verbose)
    results = scanner.detect_pqc_in_config(config_path)
    
    if not results:
        console.print(
            "[yellow]No NIST PQC algorithms detected in configuration files.[/yellow]"
        )
        return
    
    console.print(
        Panel(
            f"[bold]Found {len(results)} PQC Algorithm References[/bold]",
            style="green"
        )
    )
    
    table = Table(title="PQC Algorithm Detections")
    table.add_column("Algorithm", style="cyan")
    table.add_column("File", style="magenta")
    table.add_column("Line", style="yellow")
    table.add_column("Status", style="green")
    
    for result in results:
        for algo in result.algorithms:
            table.add_row(
                algo,
                result.file_path or "Unknown",
                str(result.line_number),
                result.details.get("nist_status", "Unknown"),
            )
    
    console.print(table)


@app.command("analyze-rsa")
def analyze_rsa(
    key_size: int = typer.Argument(..., help="RSA key size in bits"),
):
    """
    Analyze RSA key strength and quantum vulnerability.
    
    Example: chronos crypto analyze-rsa 2048
    """
    scanner = CryptoScanner()
    analysis = scanner.analyze_rsa_key(key_size)
    
    weakness_status = "[red]WEAK[/red]" if analysis["is_weak"] else "[green]STRONG[/green]"
    
    console.print(
        Panel(
            f"[bold]RSA Key Analysis: {key_size} bits[/bold]\n\n"
            f"Status: {weakness_status}\n"
            f"Quantum Vulnerable: [red]YES[/red] (Shor's algorithm)\n\n"
            f"[bold]Recommendations:[/bold]",
            style="cyan"
        )
    )
    
    for rec in analysis["recommendations"]:
        console.print(f"  • {rec}")


@app.command("analyze-ecc")
def analyze_ecc(
    curve: str = typer.Argument(..., help="ECC curve name (e.g., secp256r1)"),
    key_size: int = typer.Argument(..., help="Key size in bits"),
):
    """
    Analyze ECC key strength and quantum vulnerability.
    
    Example: chronos crypto analyze-ecc secp256r1 256
    """
    scanner = CryptoScanner()
    analysis = scanner.analyze_ecc_key(curve, key_size)
    
    weakness_status = "[red]WEAK[/red]" if analysis["is_weak"] else "[green]STRONG[/green]"
    
    console.print(
        Panel(
            f"[bold]ECC Key Analysis: {curve} ({key_size} bits)[/bold]\n\n"
            f"Status: {weakness_status}\n"
            f"Quantum Vulnerable: [red]YES[/red] (Shor's algorithm)\n\n"
            f"[bold]Recommendations:[/bold]",
            style="cyan"
        )
    )
    
    for rec in analysis["recommendations"]:
        console.print(f"  • {rec}")


@app.command("cipher-analysis")
def cipher_analysis(
    cipher1: str = typer.Argument(..., help="First cipher suite name"),
    cipher2: Optional[str] = typer.Argument(None, help="Additional cipher suite names"),
):
    """
    Analyze cipher suite strength and get recommendations.
    
    Example: chronos crypto cipher-analysis "TLS_RSA_WITH_RC4_128_MD5" "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
    """
    ciphers = [cipher1]
    if cipher2:
        ciphers.append(cipher2)
    
    recs = CipherSuiteAnalyzer.get_cipher_recommendations(ciphers)
    
    # Display weak ciphers
    if recs["weak_ciphers"]:
        console.print("[red]Weak Ciphers Found:[/red]")
        for cipher in recs["weak_ciphers"]:
            console.print(f"  ✗ {cipher}")
    
    # Display strong ciphers
    if recs["strong_ciphers"]:
        console.print("[green]Strong Ciphers:[/green]")
        for cipher in recs["strong_ciphers"]:
            console.print(f"  ✓ {cipher}")
    
    # Display recommendations
    if recs["missing"]:
        console.print("\n[yellow]Recommended Ciphers to Add:[/yellow]")
        for cipher in recs["missing"][:5]:  # Show top 5
            console.print(f"  → {cipher}")


def _display_scan_results(ssl_info):
    """Display formatted scan results."""
    
    # Protocol version
    console.print(
        f"\n[bold cyan]Active Protocol:[/bold cyan] {ssl_info.protocol_version.value}"
    )
    
    # Supported versions
    if ssl_info.supported_versions:
        console.print("[bold cyan]Supported Versions:[/bold cyan]")
        for version in ssl_info.supported_versions:
            console.print(f"  • {version.value}")
    
    # Certificate chain
    if ssl_info.certificate_chain:
        console.print(f"\n[bold cyan]Certificate Chain ({len(ssl_info.certificate_chain)} certs):[/bold cyan]")
        for i, cert in enumerate(ssl_info.certificate_chain):
            status = "[green]✓[/green]" if not cert.is_expired else "[red]✗ EXPIRED[/red]"
            console.print(f"\n  Certificate {i}: {status}")
            console.print(f"    Subject: {cert.subject}")
            console.print(f"    Issuer: {cert.issuer}")
            console.print(f"    Valid Until: {cert.not_after}")
            console.print(f"    Days Until Expiry: {cert.days_until_expiry}")
            
            if cert.key_info:
                key_status = "[red]WEAK[/red]" if cert.key_info.is_weak else "[green]STRONG[/green]"
                console.print(
                    f"    Key: {cert.key_info.algorithm.value} {cert.key_info.size} bits - {key_status}"
                )
    
    # Cipher suite
    if ssl_info.cipher_suite:
        console.print(f"\n[bold cyan]Cipher Suite:[/bold cyan] {ssl_info.cipher_suite.name}")
        console.print(f"  Strength: {ssl_info.cipher_suite.strength.value}")
    
    # Vulnerabilities
    if ssl_info.vulnerabilities:
        console.print("\n[bold red]Vulnerabilities Found:[/bold red]")
        for vuln in ssl_info.vulnerabilities:
            console.print(f"  ⚠ {vuln}")
    else:
        console.print("\n[bold green]No vulnerabilities detected![/bold green]")


if __name__ == "__main__":
    app()
