"""
CHRONOS Defend Command
======================

Commands for defensive countermeasures and protection activation.
"""

import time
from pathlib import Path
from typing import Optional, List
from enum import Enum

import typer
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn

from chronos.cli.utils import (
    error_handler, 
    print_success, 
    print_warning, 
    confirm_action,
    DefenseError,
)

console = Console()

app = typer.Typer(
    name="defend",
    help="🛡️ Defensive countermeasures and protection commands.",
    rich_markup_mode="rich",
    no_args_is_help=True,
)


class ShieldLevel(str, Enum):
    """Defense shield levels."""
    STANDARD = "standard"
    ENHANCED = "enhanced"
    MAXIMUM = "maximum"
    QUANTUM = "quantum"


class DefenseMode(str, Enum):
    """Defense operation modes."""
    PASSIVE = "passive"
    ACTIVE = "active"
    AGGRESSIVE = "aggressive"


@app.command("shield")
def shield_command(
    level: ShieldLevel = typer.Option(
        ShieldLevel.STANDARD,
        "--level",
        "-l",
        help="Shield protection level.",
    ),
    activate: bool = typer.Option(
        True,
        "--activate/--deactivate",
        "-a/-d",
        help="Activate or deactivate the shield.",
    ),
) -> None:
    """
    🛡️ Activate CHRONOS defense shield.
    
    Enables real-time protection including:
    - Threat interception
    - Anomaly detection
    - Quantum-resistant encryption
    - Automatic response
    
    [bold]Shield Levels:[/bold]
    • [green]standard[/green] - Basic protection
    • [yellow]enhanced[/yellow] - Additional monitoring
    • [red]maximum[/red] - Full defensive capabilities
    • [magenta]quantum[/magenta] - Post-quantum protection
    """
    with error_handler(console):
        action = "Activating" if activate else "Deactivating"
        status = "ACTIVE" if activate else "INACTIVE"
        color = "green" if activate else "red"
        
        console.print(Panel(
            f"[bold]{action} Shield...[/bold]\n"
            f"Level: [cyan]{level.value.upper()}[/cyan]",
            title="🛡️ Defense Shield",
            border_style="blue",
        ))
        
        with Progress(
            SpinnerColumn(),
            TextColumn("[bold blue]{task.description}"),
            console=console,
        ) as progress:
            task = progress.add_task(f"{action} shield components...", total=None)
            time.sleep(0.5)
            
            progress.update(task, description="Configuring protection rules...")
            time.sleep(0.3)
            
            progress.update(task, description="Initializing threat monitors...")
            time.sleep(0.3)
            
            progress.update(task, description="Shield ready...")
            time.sleep(0.2)
        
        console.print(Panel(
            f"[{color}]Shield Status: {status}[/{color}]\n"
            f"Protection Level: [cyan]{level.value.upper()}[/cyan]\n\n"
            f"[dim]Active Protections:[/dim]\n"
            f"  • Threat Interception: {'✓' if activate else '✗'}\n"
            f"  • Anomaly Detection: {'✓' if activate else '✗'}\n"
            f"  • Quantum Protection: {'✓' if level == ShieldLevel.QUANTUM and activate else '✗'}",
            title="Shield Status",
            border_style=color,
        ))


@app.command("quarantine")
def quarantine_command(
    target: Path = typer.Argument(
        ...,
        help="File or directory to quarantine.",
        exists=True,
    ),
    reason: str = typer.Option(
        "Manual quarantine",
        "--reason",
        "-r",
        help="Reason for quarantine.",
    ),
    force: bool = typer.Option(
        False,
        "--force",
        "-f",
        help="Skip confirmation prompt.",
    ),
) -> None:
    """
    🔒 Quarantine suspicious files or directories.
    
    Isolates potentially dangerous items:
    - Moves to secure quarantine zone
    - Removes execute permissions
    - Logs the action
    - Enables later review
    """
    with error_handler(console):
        if not force:
            confirmed = confirm_action(
                console,
                f"Quarantine [cyan]{target}[/cyan]?",
                default=False
            )
            if not confirmed:
                console.print("[yellow]Quarantine cancelled.[/yellow]")
                raise typer.Exit(0)
        
        console.print(f"[yellow]Quarantining:[/yellow] {target}")
        
        with Progress(
            SpinnerColumn(),
            TextColumn("[bold yellow]{task.description}"),
            console=console,
        ) as progress:
            task = progress.add_task("Securing target...", total=None)
            time.sleep(0.5)
            progress.update(task, description="Moving to quarantine zone...")
            time.sleep(0.3)
        
        # Placeholder - would implement actual quarantine
        console.print(f"\n[green]✓[/green] Quarantined: [cyan]{target}[/cyan]")
        console.print(f"[dim]Reason: {reason}[/dim]")
        console.print("[dim]Note: Quarantine is a placeholder in this version.[/dim]")


@app.command("mitigate")
def mitigate_command(
    threat_id: str = typer.Argument(
        ...,
        help="ID of the threat to mitigate.",
    ),
    mode: DefenseMode = typer.Option(
        DefenseMode.ACTIVE,
        "--mode",
        "-m",
        help="Mitigation mode.",
    ),
    auto_remediate: bool = typer.Option(
        False,
        "--auto-remediate",
        "-a",
        help="Automatically apply remediation.",
    ),
) -> None:
    """
    ⚔️ Mitigate a detected threat.
    
    Takes action against identified threats:
    - Blocks malicious activity
    - Patches vulnerabilities
    - Applies security fixes
    - Reports actions taken
    """
    with error_handler(console):
        console.print(Panel(
            f"[bold]Threat ID:[/bold] {threat_id}\n"
            f"[bold]Mode:[/bold] {mode.value}\n"
            f"[bold]Auto-remediate:[/bold] {auto_remediate}",
            title="⚔️ Threat Mitigation",
            border_style="red",
        ))
        
        with Progress(
            SpinnerColumn(),
            TextColumn("[bold red]{task.description}"),
            console=console,
        ) as progress:
            task = progress.add_task("Analyzing threat...", total=None)
            time.sleep(0.5)
            progress.update(task, description="Preparing countermeasures...")
            time.sleep(0.5)
            progress.update(task, description="Applying mitigation...")
            time.sleep(0.3)
        
        # Placeholder
        print_warning(console, f"Threat {threat_id} not found in threat database.")


@app.command("harden")
def harden_command(
    target: Path = typer.Argument(
        Path("."),
        help="Target to harden.",
    ),
    profile: str = typer.Option(
        "standard",
        "--profile",
        "-p",
        help="Hardening profile to apply.",
    ),
    dry_run: bool = typer.Option(
        False,
        "--dry-run",
        "-n",
        help="Show what would be changed without applying.",
    ),
) -> None:
    """
    🔧 Apply security hardening to a target.
    
    Strengthens security posture by:
    - Applying security configurations
    - Removing unnecessary permissions
    - Enabling security features
    - Configuring best practices
    """
    with error_handler(console):
        mode = "[yellow]DRY RUN[/yellow]" if dry_run else "[green]LIVE[/green]"
        
        console.print(Panel(
            f"[bold]Target:[/bold] {target.absolute()}\n"
            f"[bold]Profile:[/bold] {profile}\n"
            f"[bold]Mode:[/bold] {mode}",
            title="🔧 Security Hardening",
            border_style="blue",
        ))
        
        table = Table(title="Hardening Actions", border_style="blue")
        table.add_column("Action", style="cyan")
        table.add_column("Status", style="white")
        table.add_column("Impact", style="yellow")
        
        actions = [
            ("Enable strict permissions", "Pending", "Low"),
            ("Configure secure defaults", "Pending", "Low"),
            ("Remove debug configurations", "Pending", "Medium"),
            ("Enable security headers", "Pending", "Low"),
            ("Apply crypto best practices", "Pending", "Medium"),
        ]
        
        for action, status, impact in actions:
            table.add_row(action, status, impact)
        
        console.print(table)
        
        if dry_run:
            console.print("\n[yellow]Dry run complete.[/yellow] No changes applied.")
        else:
            console.print("\n[dim]Hardening implementation pending.[/dim]")


@app.command("status")
def status_command() -> None:
    """
    📊 Show current defense status.
    
    Displays the status of all defensive systems and countermeasures.
    """
    with error_handler(console):
        table = Table(title="Defense System Status", border_style="blue")
        table.add_column("System", style="cyan")
        table.add_column("Status", style="white")
        table.add_column("Last Updated", style="dim")
        
        systems = [
            ("Shield", "[yellow]○ Standby[/yellow]", "Not activated"),
            ("Threat Monitor", "[green]✓ Active[/green]", "Real-time"),
            ("Quarantine Zone", "[green]✓ Ready[/green]", "0 items"),
            ("Auto-Remediation", "[red]✗ Disabled[/red]", "N/A"),
            ("Quantum Shield", "[yellow]○ Standby[/yellow]", "Not activated"),
        ]
        
        for system, status, updated in systems:
            table.add_row(system, status, updated)
        
        console.print(table)
        console.print("\n[dim]Use 'chronos defend shield --activate' to enable protection.[/dim]")


# Code Scanning Commands (Phase 4: AST-based crypto code scanner)

@app.command()
def scan(
    path: str = typer.Argument(
        ".",
        help="File or directory to scan"
    ),
    output_format: str = typer.Option(
        "console",
        "--format",
        help="Output format: console, json, sarif"
    ),
    output_file: Optional[str] = typer.Option(
        None,
        "--output",
        help="Output file path"
    ),
    verbose: bool = typer.Option(
        False,
        "--verbose",
        "-v",
        help="Verbose output"
    ),
):
    """Scan code for cryptographic patterns and vulnerabilities."""
    from pathlib import Path as PathLib
    from chronos.core.defend.code_scanner import CodeScanner
    
    path_obj = PathLib(path)
    
    if not path_obj.exists():
        console.print(f"[red]✗ Path not found: {path}[/red]")
        raise typer.Exit(1)
    
    console.print(f"\n[cyan]Scanning: {path}[/cyan]\n")
    
    if path_obj.is_file():
        # Single file scan
        scanner = CodeScanner(verbose=verbose)
        with Progress() as progress:
            progress.add_task("Scanning file...", total=1)
            result = scanner.scan_file(path)
        
        if not result:
            console.print(f"[yellow]⚠ Unsupported file type: {path}[/yellow]")
            return
        
        results = [result]
    else:
        # Directory scan
        scanner = CodeScanner(verbose=verbose)
        from rich.progress import Progress
        with Progress() as progress:
            progress.add_task("Scanning directory...", total=None)
            results = scanner.scan_directory(path)
    
    # Format output
    if output_format == "json":
        _output_json(results, output_file)
    elif output_format == "sarif":
        _output_sarif(results, output_file)
    else:
        _output_console(results)
    
    console.print(f"\n[green]✓ Scan complete[/green]")


def _output_console(results):
    """Output results to console."""
    from rich.table import Table
    from rich.syntax import Syntax
    
    total_usages = sum(len(r.crypto_usages) for r in results)
    total_files = len(results)
    avg_risk = sum(r.total_risk_score for r in results) / len(results) if results else 0
    
    # Summary
    console.print("[bold cyan]Scan Summary[/bold cyan]\n")
    summary_table = Table(show_header=False)
    summary_table.add_row("Files scanned:", f"[green]{total_files}[/green]")
    summary_table.add_row("Crypto usages found:", f"[yellow]{total_usages}[/yellow]")
    summary_table.add_row("Average risk score:", f"[red]{avg_risk:.1f}/100[/red]")
    console.print(summary_table)
    
    # Results by file
    for result in results:
        console.print(f"\n[bold cyan]File: {result.file_path}[/bold cyan]")
        console.print(f"Language: {result.language} | Risk Score: {result.total_risk_score:.1f}/100")
        
        if not result.crypto_usages:
            console.print("[dim]No cryptographic usages detected[/dim]")
            continue
        
        # Crypto usages table
        table = Table(show_header=True, header_style="bold magenta")
        table.add_column("Line", style="cyan", width=6)
        table.add_column("Algorithm", style="yellow")
        table.add_column("Type", width=20)
        table.add_column("Risk", width=10)
        table.add_column("Recommendation", width=40)
        
        for usage in result.crypto_usages:
            risk_color = {
                'critical': 'red',
                'high': 'red',
                'medium': 'yellow',
                'low': 'green',
                'info': 'blue',
            }.get(usage.risk_level.value, 'white')
            
            rec = usage.recommendation or "-"
            table.add_row(
                str(usage.location.line),
                usage.algorithm.value,
                usage.usage_type,
                f"[{risk_color}]{usage.risk_level.value.upper()}[/{risk_color}]",
                rec[:40] + "..." if len(rec) > 40 else rec
            )
        
        console.print(table)
        
        # Migration plans
        if result.migration_plans:
            console.print(f"\n[bold cyan]Migration Plans ({len(result.migration_plans)})[/bold cyan]")
            plan_table = Table(show_header=True, header_style="bold magenta")
            plan_table.add_column("From", style="cyan")
            plan_table.add_column("To", style="green")
            plan_table.add_column("Priority", width=10)
            plan_table.add_column("Effort", width=12)
            
            for plan in result.migration_plans:
                priority_color = {
                    'critical': 'red',
                    'high': 'orange1',
                    'medium': 'yellow',
                    'low': 'green',
                }.get(plan.priority, 'white')
                
                plan_table.add_row(
                    plan.from_algorithm,
                    plan.to_algorithm,
                    f"[{priority_color}]{plan.priority.upper()}[/{priority_color}]",
                    f"{plan.effort_hours:.0f}h (~{plan.timeline_months:.1f}m)"
                )
            
            console.print(plan_table)


def _output_json(results, output_file: Optional[str]):
    """Output results as JSON."""
    import json
    from datetime import datetime
    
    data = {
        'scan_date': datetime.now().isoformat(),
        'total_files': len(results),
        'files': []
    }
    
    for result in results:
        file_data = {
            'file_path': result.file_path,
            'language': result.language,
            'risk_score': result.total_risk_score,
            'crypto_usages': [
                {
                    'line': u.location.line,
                    'column': u.location.column,
                    'algorithm': u.algorithm.value,
                    'type': u.usage_type,
                    'risk_level': u.risk_level.value,
                    'recommendation': u.recommendation,
                    'code_snippet': u.location.code_snippet[:100] + "..." if len(u.location.code_snippet) > 100 else u.location.code_snippet,
                }
                for u in result.crypto_usages
            ],
            'migration_plans': [
                {
                    'from': p.from_algorithm,
                    'to': p.to_algorithm,
                    'priority': p.priority,
                    'effort_hours': p.effort_hours,
                    'timeline_months': p.timeline_months,
                }
                for p in result.migration_plans
            ]
        }
        data['files'].append(file_data)
    
    if output_file:
        with open(output_file, 'w') as f:
            json.dump(data, f, indent=2)
        console.print(f"[green]✓[/green] JSON report: {output_file}")
    else:
        console.print(json.dumps(data, indent=2))


def _output_sarif(results, output_file: Optional[str]):
    """Output results in SARIF format."""
    import json
    from chronos.core.defend.code_scanner import CodeScanner
    
    scanner = CodeScanner()
    sarif = scanner.generate_sarif_report(results, output_file)
    
    if output_file:
        console.print(f"[green]✓[/green] SARIF report: {output_file}")
    else:
        console.print(json.dumps(sarif, indent=2))


@app.command()
def dependencies(
    path: str = typer.Argument(
        ".",
        help="Path to project with requirements.txt"
    ),
    output_format: str = typer.Option(
        "console",
        "--format",
        help="Output format: console, json"
    ),
):
    """Analyze project dependencies for cryptographic libraries."""
    from pathlib import Path as PathLib
    from chronos.core.defend.code_scanner import CodeScanner
    
    req_file = PathLib(path) / "requirements.txt"
    
    if not req_file.exists():
        # Try finding it
        if PathLib(path).is_file() and path.endswith("requirements.txt"):
            req_file = PathLib(path)
        else:
            console.print(f"[red]✗ requirements.txt not found in {path}[/red]")
            raise typer.Exit(1)
    
    console.print(f"\n[cyan]Analyzing dependencies: {req_file}[/cyan]\n")
    
    scanner = CodeScanner()
    deps = scanner.analyze_dependencies(str(req_file))
    
    if output_format == "json":
        import json
        data = {
            'file': str(req_file),
            'total_dependencies': len(deps),
            'crypto_libraries': [
                {
                    'name': d.name,
                    'version': d.version,
                    'is_crypto': d.is_crypto,
                    'has_pqc': d.has_pqc,
                }
                for d in deps if d.is_crypto
            ],
            'all_dependencies': [
                {
                    'name': d.name,
                    'version': d.version,
                    'source': d.source,
                }
                for d in deps
            ]
        }
        console.print(json.dumps(data, indent=2))
    else:
        # Console output
        table = Table(show_header=True, header_style="bold magenta")
        table.add_column("Package", style="cyan")
        table.add_column("Version", style="yellow")
        table.add_column("Crypto", width=8)
        table.add_column("PQC Support", width=12)
        
        for dep in deps:
            crypto_str = "[green]✓[/green]" if dep.is_crypto else "[dim]-[/dim]"
            pqc_str = "[green]✓[/green]" if dep.has_pqc else "[dim]-[/dim]"
            
            table.add_row(
                dep.name,
                dep.version or "unknown",
                crypto_str,
                pqc_str
            )
        
        console.print(table)
        console.print(f"\n[cyan]Total dependencies:[/cyan] {len(deps)}")
        crypto_count = sum(1 for d in deps if d.is_crypto)
        console.print(f"[cyan]Cryptographic libraries:[/cyan] {crypto_count}")
