"""
CHRONOS Analyze Command
=======================

Commands for cryptographic analysis and vulnerability assessment.
"""

import time
import re
from pathlib import Path
from typing import Optional, List, Dict, Tuple
from enum import Enum
from collections import defaultdict

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

from chronos.cli.utils import error_handler, print_success, print_warning, AnalysisError

console = Console()

app = typer.Typer(
    name="analyze",
    help="📊 Cryptographic analysis and vulnerability assessment commands.",
    rich_markup_mode="rich",
    no_args_is_help=True,
)


class CryptoScanner:
    """Real cryptographic analysis engine."""
    
    def __init__(self):
        self.crypto_patterns = {
            'rsa': {
                'patterns': [
                    r'RSA\.generate\(\s*(\d+)',
                    r'rsa\.generate\(\s*(\d+)',
                    r'RSA\(key_size=(\d+)',
                    r'RSAKey\((\d+)\)',
                ],
                'quantum_safe': False,
                'min_key_size': 2048,
            },
            'ecc': {
                'patterns': [
                    r'ECC\.generate\(\s*(\w+)',
                    r'ECDSA\((\w+)\)',
                    r'P-(\d+)',
                    r'secp(\d+r1)',
                ],
                'quantum_safe': False,
                'min_key_size': 256,
            },
            'aes': {
                'patterns': [
                    r'AES\.new',
                    r'from.*Crypto.*AES',
                    r'import.*AES',
                    r'Cipher\(algorithms\.AES',
                ],
                'quantum_safe': True,
                'min_key_size': 256,
            },
            'sha': {
                'patterns': [
                    r'SHA-?(\d+)',
                    r'hashlib\.sha(\d+)',
                    r'sha(\d+)',
                ],
                'quantum_safe': False,
                'weak_variants': ['1', '224'],
            },
            'des': {
                'patterns': [
                    r'DES\.new',
                    r'TripleDES',
                    r'DES3',
                ],
                'quantum_safe': False,
                'vulnerable': True,
            },
            'md5': {
                'patterns': [
                    r'md5\(',
                    r'MD5\(',
                    r'hashlib\.md5',
                ],
                'quantum_safe': False,
                'vulnerable': True,
            },
        }
    
    def scan_directory(self, target: Path, algorithm: str = 'all') -> Dict:
        """Scan directory for crypto usage."""
        results = defaultdict(list)
        files_scanned = 0
        
        # Collect Python and JS files
        if target.is_file():
            files = [target]
        else:
            files = list(target.rglob('*.py')) + list(target.rglob('*.js')) + list(target.rglob('*.ts'))
        
        for file_path in files:
            if '__pycache__' in str(file_path):
                continue
            
            files_scanned += 1
            try:
                with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                    content = f.read()
                    lines = content.split('\n')
                    
                    # Scan for each algorithm
                    for algo, config in self.crypto_patterns.items():
                        if algorithm != 'all' and algo != algorithm:
                            continue
                        
                        for i, line in enumerate(lines):
                            for pattern in config['patterns']:
                                if re.search(pattern, line, re.IGNORECASE):
                                    results[algo].append({
                                        'file': str(file_path),
                                        'line': i + 1,
                                        'code': line.strip(),
                                        'config': config,
                                    })
            except:
                pass
        
        return dict(results), files_scanned
    
    def analyze_security(self, findings: Dict) -> Dict:
        """Analyze security implications of findings."""
        analysis = {
            'quantum_safe': 0,
            'quantum_unsafe': 0,
            'vulnerable': 0,
            'weak': 0,
            'recommendations': []
        }
        
        for algo, instances in findings.items():
            config = self.crypto_patterns.get(algo, {})
            
            if config.get('vulnerable'):
                analysis['vulnerable'] += len(instances)
                analysis['recommendations'].append(f"⚠️  {algo.upper()} is deprecated and vulnerable. Immediately migrate to AES or other modern ciphers.")
            elif not config.get('quantum_safe'):
                analysis['quantum_unsafe'] += len(instances)
                if algo == 'rsa':
                    analysis['recommendations'].append("RSA and ECC are vulnerable to quantum attacks. Plan migration to post-quantum alternatives like Kyber or Dilithium.")
            else:
                analysis['quantum_safe'] += len(instances)
        
        return analysis


class CryptoAlgorithm(str, Enum):
    """Cryptographic algorithms for analysis."""
    RSA = "rsa"
    ECC = "ecc"
    AES = "aes"
    SHA = "sha"
    ALL = "all"


class AnalysisDepth(str, Enum):
    """Analysis depth levels."""
    QUICK = "quick"
    STANDARD = "standard"
    DEEP = "deep"


# Initialize scanner
crypto_scanner = CryptoScanner()


@app.command("crypto")
def crypto_command(
    target: Path = typer.Argument(
        Path("."),
        help="Target path to analyze for cryptographic usage.",
    ),
    algorithm: CryptoAlgorithm = typer.Option(
        CryptoAlgorithm.ALL,
        "--algorithm",
        "-a",
        help="Specific algorithm to analyze.",
    ),
    quantum_check: bool = typer.Option(
        True,
        "--quantum/--no-quantum",
        "-q/-Q",
        help="Check for quantum vulnerability.",
    ),
) -> None:
    """
    🔐 Analyze cryptographic implementations.
    
    Scans code for cryptographic usage and evaluates:
    - Algorithm strength and configuration
    - Key sizes and generation methods
    - Quantum vulnerability assessment
    - Best practice compliance
    
    [bold]Examples:[/bold]
        chronos analyze crypto ./src
        chronos analyze crypto . --algorithm rsa --quantum
    """
    with error_handler(console):
        console.print(Panel(
            f"[bold]Target:[/bold] {target.absolute()}\n"
            f"[bold]Algorithm:[/bold] {algorithm.value}\n"
            f"[bold]Quantum Check:[/bold] {quantum_check}",
            title="🔐 Cryptographic Analysis",
            border_style="blue",
        ))
        
        # Real scanning
        with Progress(
            SpinnerColumn(),
            TextColumn("[bold blue]{task.description}"),
            console=console,
        ) as progress:
            progress.add_task("Scanning for crypto implementations...", total=None)
            findings, files_scanned = crypto_scanner.scan_directory(target, algorithm.value)
        
        # Results table
        table = Table(title="Cryptographic Analysis Results", border_style="blue")
        table.add_column("Algorithm", style="cyan")
        table.add_column("Instances", style="white")
        table.add_column("Strength", style="green")
        table.add_column("Quantum Safe", style="yellow")
        
        # Display results
        total_findings = 0
        for algo in ['rsa', 'ecc', 'aes', 'sha', 'des', 'md5']:
            count = len(findings.get(algo, []))
            total_findings += count
            
            if algo == 'rsa':
                strength = "Adequate"
                quantum = "[red]No[/red]"
            elif algo == 'ecc':
                strength = "Strong"
                quantum = "[red]No[/red]"
            elif algo == 'aes':
                strength = "Strong"
                quantum = "[green]Yes[/green]"
            elif algo == 'sha':
                strength = "Strong"
                quantum = "[yellow]Partial[/yellow]"
            elif algo == 'des':
                strength = "[red]Weak[/red]"
                quantum = "[red]No[/red]"
            elif algo == 'md5':
                strength = "[red]Broken[/red]"
                quantum = "[red]No[/red]"
            
            table.add_row(algo.upper(), str(count), strength, quantum)
        
        console.print(table)
        console.print(f"\n[dim]Files scanned: {files_scanned}[/dim]")
        
        if total_findings > 0:
            console.print(f"\n[yellow]Found {total_findings} cryptographic implementations[/yellow]\n")
            
            # Show details
            for algo, instances in findings.items():
                if instances:
                    console.print(f"\n[bold cyan]{algo.upper()}[/bold cyan] ({len(instances)} instances):")
                    for inst in instances[:3]:  # Show first 3
                        console.print(f"  • {inst['file']}:{inst['line']}")
                        console.print(f"    [dim]{inst['code']}[/dim]")
                    if len(instances) > 3:
                        console.print(f"  ... and {len(instances) - 3} more")
        
        # Analysis
        analysis = crypto_scanner.analyze_security(findings)
        
        if quantum_check and analysis['recommendations']:
            console.print(Panel(
                "\n".join(analysis['recommendations']),
                title="⚠️ Security Recommendations",
                border_style="yellow",
            ))


@app.command("vulnerabilities")
def vulnerabilities_command(
    target: Path = typer.Argument(
        Path("."),
        help="Target to scan for vulnerabilities.",
    ),
    depth: AnalysisDepth = typer.Option(
        AnalysisDepth.STANDARD,
        "--depth",
        "-d",
        help="Analysis depth level.",
    ),
    cve_check: bool = typer.Option(
        True,
        "--cve/--no-cve",
        help="Check against CVE database.",
    ),
) -> None:
    """
    🔍 Scan for security vulnerabilities.
    
    Performs vulnerability assessment including:
    - Known CVE detection
    - Dependency vulnerabilities
    - Configuration weaknesses
    - Code security patterns
    """
    with error_handler(console):
        console.print(Panel(
            f"[bold]Target:[/bold] {target.absolute()}\n"
            f"[bold]Depth:[/bold] {depth.value}\n"
            f"[bold]CVE Check:[/bold] {cve_check}",
            title="🔍 Vulnerability Analysis",
            border_style="blue",
        ))
        
        # Real vulnerability patterns
        vuln_patterns = {
            'sql_injection': {
                'patterns': [
                    r'execute\s*\(\s*["\'].*\+.*["\']',
                    r'query\s*=\s*f["\'].*{.*}',
                    r'SELECT.*FROM.*WHERE.*\+',
                ],
                'severity': 'Critical',
                'description': 'SQL Injection vulnerability'
            },
            'command_injection': {
                'patterns': [
                    r'os\.system\s*\(\s*f["\'].*{.*}',
                    r'subprocess\..*shell\s*=\s*True',
                    r'eval\s*\(',
                ],
                'severity': 'Critical',
                'description': 'Command Injection vulnerability'
            },
            'hardcoded_secret': {
                'patterns': [
                    r'password\s*=\s*["\'].*["\']',
                    r'api_key\s*=\s*["\'][A-Za-z0-9_]+["\']',
                    r'secret\s*=\s*["\'].*["\']',
                ],
                'severity': 'High',
                'description': 'Hardcoded secret/credential'
            },
            'insecure_random': {
                'patterns': [
                    r'import\s+random',
                    r'random\.choice|random\.seed|random\.random\(\)',
                ],
                'severity': 'High',
                'description': 'Insecure random number generation'
            },
            'weak_hash': {
                'patterns': [
                    r'hashlib\.md5|hashlib\.sha1',
                    r'MD5|SHA1',
                ],
                'severity': 'Medium',
                'description': 'Weak hash algorithm'
            },
        }
        
        vulnerabilities = defaultdict(list)
        files_scanned = 0
        
        # Collect files
        if target.is_file():
            files = [target]
        else:
            files = list(target.rglob('*.py')) + list(target.rglob('*.js')) + list(target.rglob('*.ts'))
        
        with Progress(
            SpinnerColumn(),
            TextColumn("[bold blue]{task.description}"),
            console=console,
        ) as progress:
            progress.add_task("Scanning for vulnerabilities...", total=None)
            
            for file_path in files:
                if '__pycache__' in str(file_path) or '.git' in str(file_path):
                    continue
                
                files_scanned += 1
                try:
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                        content = f.read()
                        lines = content.split('\n')
                        
                        for i, line in enumerate(lines):
                            for vuln_type, config in vuln_patterns.items():
                                for pattern in config['patterns']:
                                    if re.search(pattern, line, re.IGNORECASE):
                                        vulnerabilities[vuln_type].append({
                                            'file': str(file_path),
                                            'line': i + 1,
                                            'code': line.strip(),
                                            'severity': config['severity'],
                                            'description': config['description'],
                                        })
                except:
                    pass
        
        # Display results
        severity_count = {'Critical': 0, 'High': 0, 'Medium': 0, 'Low': 0}
        for vuln_type, instances in vulnerabilities.items():
            severity = vuln_patterns[vuln_type]['severity']
            severity_count[severity] += len(instances)
        
        table = Table(title="Vulnerability Report", border_style="blue")
        table.add_column("Severity", style="cyan")
        table.add_column("Count", style="white")
        
        table.add_row("[red]Critical[/red]", str(severity_count['Critical']))
        table.add_row("[orange3]High[/orange3]", str(severity_count['High']))
        table.add_row("[yellow]Medium[/yellow]", str(severity_count['Medium']))
        table.add_row("[green]Low[/green]", str(severity_count['Low']))
        
        console.print(table)
        console.print(f"\n[dim]Files scanned: {files_scanned}[/dim]\n")
        
        if sum(severity_count.values()) > 0:
            for vuln_type, instances in vulnerabilities.items():
                if instances:
                    severity = vuln_patterns[vuln_type]['severity']
                    color_map = {'Critical': 'red', 'High': 'orange3', 'Medium': 'yellow', 'Low': 'green'}
                    console.print(f"\n[{color_map[severity]}]●[/{color_map[severity]}] {vuln_type.upper()} ({len(instances)} instances):")
                    for inst in instances[:2]:
                        console.print(f"  [bold]{inst['file']}:{inst['line']}[/bold]")
                        console.print(f"  [dim]{inst['code']}[/dim]")
                    if len(instances) > 2:
                        console.print(f"  ... and {len(instances) - 2} more")
        else:
            print_success(console, "No vulnerabilities detected", "Analysis Complete")


@app.command("report")
def report_command(
    target: Path = typer.Argument(
        Path("."),
        help="Target to generate report for.",
    ),
    output: Path = typer.Option(
        Path("chronos-report.html"),
        "--output",
        "-o",
        help="Output file path for the report.",
    ),
    format: str = typer.Option(
        "html",
        "--format",
        "-f",
        help="Report format (html, pdf, json, markdown).",
    ),
) -> None:
    """
    📄 Generate comprehensive security analysis report.
    
    Creates a detailed report including:
    - Executive summary
    - Threat analysis results
    - Cryptographic assessment
    - Vulnerability findings
    - Remediation recommendations
    """
    with error_handler(console):
        console.print(f"[blue]Generating {format.upper()} report for {target}...[/blue]")
        
        # Generate content
        findings, files_scanned = crypto_scanner.scan_directory(target, 'all')
        analysis = crypto_scanner.analyze_security(findings)
        
        # Build report content
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
        
        report_content = f"""
# Chronos Security Analysis Report
**Generated:** {timestamp}
**Target:** {target.absolute()}
**Files Scanned:** {files_scanned}

## Executive Summary
This report provides a comprehensive security analysis of the target codebase.

## Cryptographic Analysis
### Findings
- Quantum-Safe Algorithms: {analysis['quantum_safe']}
- Quantum-Unsafe Algorithms: {analysis['quantum_unsafe']}
- Vulnerable Algorithms: {analysis['vulnerable']}

### Algorithm Breakdown
- RSA Instances: {len(findings.get('rsa', []))}
- ECC Instances: {len(findings.get('ecc', []))}
- AES Instances: {len(findings.get('aes', []))}
- SHA Instances: {len(findings.get('sha', []))}
- DES Instances: {len(findings.get('des', []))}
- MD5 Instances: {len(findings.get('md5', []))}

## Recommendations
"""
        
        for rec in analysis['recommendations']:
            report_content += f"- {rec}\n"
        
        report_content += "\n## Conclusion\nRegular updates and monitoring are recommended.\n"
        
        # Save report
        output_path = Path(output)
        output_path.parent.mkdir(parents=True, exist_ok=True)
        
        if format.lower() == 'json':
            import json
            report_data = {
                'timestamp': timestamp,
                'target': str(target.absolute()),
                'files_scanned': files_scanned,
                'crypto_findings': findings,
                'analysis': analysis,
            }
            with open(output_path, 'w') as f:
                json.dump(report_data, f, indent=2)
        elif format.lower() == 'markdown':
            output_path = output_path.with_suffix('.md')
            with open(output_path, 'w') as f:
                f.write(report_content)
        else:  # HTML
            html_content = f"""
<html>
<head>
    <title>Chronos Security Report</title>
    <style>
        body {{ font-family: Arial; margin: 20px; }}
        h1 {{ color: #2c3e50; }}
        table {{ border-collapse: collapse; width: 100%; margin: 10px 0; }}
        th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
        th {{ background-color: #3498db; color: white; }}
        .summary {{ background-color: #ecf0f1; padding: 10px; border-radius: 5px; }}
    </style>
</head>
<body>
    <h1>Chronos Security Analysis Report</h1>
    <div class="summary">
        <p><strong>Generated:</strong> {timestamp}</p>
        <p><strong>Target:</strong> {target.absolute()}</p>
        <p><strong>Files Scanned:</strong> {files_scanned}</p>
    </div>
    <h2>Cryptographic Analysis</h2>
    <table>
        <tr><th>Algorithm</th><th>Instances</th></tr>
        <tr><td>RSA</td><td>{len(findings.get('rsa', []))}</td></tr>
        <tr><td>ECC</td><td>{len(findings.get('ecc', []))}</td></tr>
        <tr><td>AES</td><td>{len(findings.get('aes', []))}</td></tr>
        <tr><td>SHA</td><td>{len(findings.get('sha', []))}</td></tr>
        <tr><td>DES</td><td>{len(findings.get('des', []))}</td></tr>
        <tr><td>MD5</td><td>{len(findings.get('md5', []))}</td></tr>
    </table>
    <h2>Recommendations</h2>
    <ul>
"""
            for rec in analysis['recommendations']:
                html_content += f"        <li>{rec}</li>\n"
            
            html_content += """
    </ul>
</body>
</html>
"""
            with open(output_path, 'w') as f:
                f.write(html_content)
        
        print_success(console, f"Report generated: [cyan]{output_path}[/cyan]", "Report Generated")


@app.command("quantum-readiness")
def quantum_readiness_command(
    target: Path = typer.Argument(
        Path("."),
        help="Target to assess quantum readiness.",
    ),
) -> None:
    """
    ⚛️ Assess quantum computing readiness.
    
    Evaluates your system's preparedness for quantum threats:
    - Current cryptographic inventory
    - Quantum-vulnerable algorithms
    - Migration recommendations
    - Post-quantum alternatives
    """
    with error_handler(console):
        console.print(Panel(
            f"[bold]Assessing:[/bold] {target.absolute()}",
            title="⚛️ Quantum Readiness Assessment",
            border_style="magenta",
        ))
        
        # Scan for crypto
        findings, files_scanned = crypto_scanner.scan_directory(target, 'all')
        analysis = crypto_scanner.analyze_security(findings)
        
        # Calculate readiness score
        total_instances = sum(len(v) for v in findings.values())
        quantum_safe_count = analysis['quantum_safe']
        quantum_unsafe_count = analysis['quantum_unsafe']
        vulnerable_count = analysis['vulnerable']
        
        if total_instances == 0:
            readiness_score = 100  # No crypto = no quantum risk
            assessment = "Complete"
        else:
            # Score based on percentage of quantum-safe implementations
            readiness_score = int((quantum_safe_count / total_instances) * 100)
            
            if readiness_score >= 80:
                assessment = "Good"
            elif readiness_score >= 60:
                assessment = "Fair"
            elif readiness_score >= 40:
                assessment = "Poor"
            else:
                assessment = "Critical"
        
        # Migration effort estimate
        if quantum_unsafe_count == 0:
            effort = "None"
        elif quantum_unsafe_count <= 5:
            effort = "Low"
        elif quantum_unsafe_count <= 15:
            effort = "Medium"
        else:
            effort = "High"
        
        summary = f"""[bold]Quantum Readiness Score:[/bold] [yellow]{readiness_score}%[/yellow] ([cyan]{assessment}[/cyan])

[bold]Summary:[/bold]
• Total crypto implementations: {total_instances}
• Quantum-safe: [green]{quantum_safe_count}[/green]
• Quantum-unsafe (RSA/ECC): [yellow]{quantum_unsafe_count}[/yellow]
• Vulnerable (DES/MD5): [red]{vulnerable_count}[/red]

[bold]Migration Effort:[/bold] {effort}

[bold]Timeline:[/bold]
Phase 1 (0-6 months): Inventory and assessment [green]✓[/green]
Phase 2 (6-12 months): Implement crypto-agility
Phase 3 (12-24 months): Deploy post-quantum alternatives
Phase 4 (2+ years): Full migration to hybrid cryptography"""
        
        console.print(Panel(
            summary,
            title="Assessment Results",
            border_style="magenta",
        ))
        
        if analysis['recommendations']:
            console.print(Panel(
                "\n".join(analysis['recommendations']),
                title="⚠️ Recommendations",
                border_style="yellow",
            ))
        
        console.print(f"\n[dim]Files scanned: {files_scanned}[/dim]")
