use crate::types::{ImpactType, Severity, VulnerabilityType};

use super::{MigrationImpactTemplate, Rule, RulePattern};

/// Get all cryptographic vulnerability rules
pub fn get_crypto_rules() -> Vec<Rule> {
    vec![
        // RSA Rules
        Rule {
            id: "KYBER-001".to_string(),
            name: "RSA Encryption Detected".to_string(),
            description: "RSA encryption is vulnerable to quantum attacks using Shor's algorithm. \
                All RSA key sizes will be broken by a sufficiently powerful quantum computer."
                .to_string(),
            vuln_type: VulnerabilityType::Rsa2048,
            severity: Severity::Critical,
            patterns: vec![
                RulePattern::FunctionCall {
                    names: vec![
                        "generateKeyPair".to_string(),
                        "generateKeyPairSync".to_string(),
                        "createSign".to_string(),
                        "createVerify".to_string(),
                        "publicEncrypt".to_string(),
                        "privateDecrypt".to_string(),
                        "RSA_generate_key".to_string(),
                        "RSA_new".to_string(),
                        "RSA_public_encrypt".to_string(),
                        "RSA_private_decrypt".to_string(),
                    ],
                    module: None,
                },
                RulePattern::StringLiteral {
                    patterns: vec![
                        "rsa".to_string(),
                        "RSA".to_string(),
                        "RSA-OAEP".to_string(),
                        "RSA-PSS".to_string(),
                        "RSASSA-PKCS1-v1_5".to_string(),
                    ],
                },
                RulePattern::Import {
                    modules: vec!["rsa".to_string(), "Crypto.PublicKey.RSA".to_string()],
                    symbols: vec!["RSA".to_string()],
                },
                RulePattern::MethodCall {
                    object_type: Some("crypto".to_string()),
                    method_names: vec!["generateKeyPair".to_string(), "generateKeyPairSync".to_string()],
                },
            ],
            recommendation: "Migrate to CRYSTALS-Kyber (ML-KEM) for key encapsulation or CRYSTALS-Dilithium \
                (ML-DSA) for digital signatures. Consider hybrid approaches during transition."
                .to_string(),
            cwe_id: Some("CWE-327".to_string()),
            migration_impacts: vec![
                MigrationImpactTemplate {
                    impact_type: ImpactType::ArchitecturalRefactor,
                    description: "RSA direct encryption must be replaced with Key Encapsulation Mechanism (KEM) + \
                        symmetric encryption pattern."
                        .to_string(),
                    estimated_effort: "High".to_string(),
                    recommendation: "Implement Kyber KEM to establish shared secret, then use AES-256-GCM for \
                        actual encryption."
                        .to_string(),
                },
                MigrationImpactTemplate {
                    impact_type: ImpactType::DatabaseSchema,
                    description: "Kyber public keys are 1184 bytes (vs RSA-2048's 256 bytes). Database columns \
                        storing keys will need expansion."
                        .to_string(),
                    estimated_effort: "Medium".to_string(),
                    recommendation: "Audit database schemas and increase key storage columns to accommodate \
                        larger PQC keys."
                        .to_string(),
                },
                MigrationImpactTemplate {
                    impact_type: ImpactType::ApiPayload,
                    description: "Larger key sizes may impact API payload sizes and network performance."
                        .to_string(),
                    estimated_effort: "Low".to_string(),
                    recommendation: "Review API payload limits and consider compression or pagination strategies."
                        .to_string(),
                },
            ],
        },
        // ECDSA/ECDH Rules
        Rule {
            id: "KYBER-002".to_string(),
            name: "Elliptic Curve Cryptography Detected".to_string(),
            description: "ECDSA and ECDH are vulnerable to quantum attacks using Shor's algorithm. \
                All elliptic curve cryptography will be broken by quantum computers."
                .to_string(),
            vuln_type: VulnerabilityType::Ecdsa,
            severity: Severity::Critical,
            patterns: vec![
                RulePattern::FunctionCall {
                    names: vec![
                        "createECDH".to_string(),
                        "EC_KEY_new".to_string(),
                        "EC_KEY_generate_key".to_string(),
                        "ECDSA_sign".to_string(),
                        "ECDSA_verify".to_string(),
                    ],
                    module: None,
                },
                RulePattern::StringLiteral {
                    patterns: vec![
                        "ec".to_string(),
                        "ecdsa".to_string(),
                        "ecdh".to_string(),
                        "ECDSA".to_string(),
                        "ECDH".to_string(),
                        "secp256k1".to_string(),
                        "secp384r1".to_string(),
                        "secp521r1".to_string(),
                        "prime256v1".to_string(),
                        "P-256".to_string(),
                        "P-384".to_string(),
                        "P-521".to_string(),
                    ],
                },
                RulePattern::Import {
                    modules: vec![
                        "ecdsa".to_string(),
                        "Crypto.PublicKey.ECC".to_string(),
                        "elliptic".to_string(),
                    ],
                    symbols: vec!["ECDSA".to_string(), "ECC".to_string(), "ec".to_string()],
                },
            ],
            recommendation: "Migrate to CRYSTALS-Dilithium (ML-DSA) for signatures or CRYSTALS-Kyber (ML-KEM) \
                for key exchange. Consider hybrid ECDH+Kyber during transition."
                .to_string(),
            cwe_id: Some("CWE-327".to_string()),
            migration_impacts: vec![
                MigrationImpactTemplate {
                    impact_type: ImpactType::ArchitecturalRefactor,
                    description: "ECDH key exchange must be replaced with Kyber KEM."
                        .to_string(),
                    estimated_effort: "Medium".to_string(),
                    recommendation: "Replace ECDH with Kyber KEM for key establishment protocols."
                        .to_string(),
                },
                MigrationImpactTemplate {
                    impact_type: ImpactType::CertificateInfrastructure,
                    description: "TLS certificates using ECDSA must be replaced with PQC alternatives."
                        .to_string(),
                    estimated_effort: "High".to_string(),
                    recommendation: "Plan PKI migration to support Dilithium or hybrid certificates."
                        .to_string(),
                },
            ],
        },
        // DSA Rule
        Rule {
            id: "KYBER-003".to_string(),
            name: "DSA Signature Detected".to_string(),
            description: "DSA is vulnerable to quantum attacks using Shor's algorithm."
                .to_string(),
            vuln_type: VulnerabilityType::Dsa,
            severity: Severity::Critical,
            patterns: vec![
                RulePattern::FunctionCall {
                    names: vec![
                        "DSA_generate_key".to_string(),
                        "DSA_sign".to_string(),
                        "DSA_verify".to_string(),
                    ],
                    module: None,
                },
                RulePattern::StringLiteral {
                    patterns: vec!["dsa".to_string(), "DSA".to_string()],
                },
                RulePattern::Import {
                    modules: vec!["Crypto.PublicKey.DSA".to_string()],
                    symbols: vec!["DSA".to_string()],
                },
            ],
            recommendation: "Migrate to CRYSTALS-Dilithium (ML-DSA) or SPHINCS+ for digital signatures."
                .to_string(),
            cwe_id: Some("CWE-327".to_string()),
            migration_impacts: vec![MigrationImpactTemplate {
                impact_type: ImpactType::ArchitecturalRefactor,
                description: "DSA signatures must be replaced with PQC signature schemes."
                    .to_string(),
                estimated_effort: "Medium".to_string(),
                recommendation: "Migrate to Dilithium for general use or SPHINCS+ for hash-based security."
                    .to_string(),
            }],
        },
        // Diffie-Hellman Rule
        Rule {
            id: "KYBER-004".to_string(),
            name: "Diffie-Hellman Key Exchange Detected".to_string(),
            description: "DH key exchange is vulnerable to quantum attacks using Shor's algorithm."
                .to_string(),
            vuln_type: VulnerabilityType::DhKeyExchange,
            severity: Severity::Critical,
            patterns: vec![
                RulePattern::FunctionCall {
                    names: vec![
                        "createDiffieHellman".to_string(),
                        "createDiffieHellmanGroup".to_string(),
                        "getDiffieHellman".to_string(),
                        "DH_generate_key".to_string(),
                        "DH_compute_key".to_string(),
                    ],
                    module: None,
                },
                RulePattern::StringLiteral {
                    patterns: vec![
                        "diffie-hellman".to_string(),
                        "DiffieHellman".to_string(),
                        "modp".to_string(),
                    ],
                },
                RulePattern::MethodCall {
                    object_type: Some("crypto".to_string()),
                    method_names: vec![
                        "createDiffieHellman".to_string(),
                        "getDiffieHellman".to_string(),
                    ],
                },
            ],
            recommendation: "Migrate to CRYSTALS-Kyber (ML-KEM) for key exchange."
                .to_string(),
            cwe_id: Some("CWE-327".to_string()),
            migration_impacts: vec![
                MigrationImpactTemplate {
                    impact_type: ImpactType::ProtocolChange,
                    description: "DH-based protocols must be updated to use KEM-based key exchange."
                        .to_string(),
                    estimated_effort: "High".to_string(),
                    recommendation: "Update protocol implementations to use Kyber KEM."
                        .to_string(),
                },
            ],
        },
        // SHA-1 Rule (not quantum-specific but important)
        Rule {
            id: "KYBER-005".to_string(),
            name: "SHA-1 Hash Function Detected".to_string(),
            description: "SHA-1 is cryptographically broken and should not be used. While not \
                quantum-specific, it should be replaced during PQC migration."
                .to_string(),
            vuln_type: VulnerabilityType::Sha1,
            severity: Severity::High,
            patterns: vec![
                RulePattern::FunctionCall {
                    names: vec!["createHash".to_string(), "SHA1".to_string()],
                    module: None,
                },
                RulePattern::StringLiteral {
                    patterns: vec!["sha1".to_string(), "SHA1".to_string(), "sha-1".to_string()],
                },
            ],
            recommendation: "Replace with SHA-256 or SHA-3. For quantum resistance, use SHA-3 or \
                increase hash output size."
                .to_string(),
            cwe_id: Some("CWE-328".to_string()),
            migration_impacts: vec![MigrationImpactTemplate {
                impact_type: ImpactType::DatabaseSchema,
                description: "Hash storage may need to accommodate larger hash outputs."
                    .to_string(),
                estimated_effort: "Low".to_string(),
                recommendation: "Ensure database columns can store 256-bit or larger hashes."
                    .to_string(),
            }],
        },
        // MD5 Rule
        Rule {
            id: "KYBER-006".to_string(),
            name: "MD5 Hash Function Detected".to_string(),
            description: "MD5 is cryptographically broken and must not be used for security purposes."
                .to_string(),
            vuln_type: VulnerabilityType::Md5,
            severity: Severity::High,
            patterns: vec![
                RulePattern::FunctionCall {
                    names: vec!["MD5".to_string()],
                    module: None,
                },
                RulePattern::StringLiteral {
                    patterns: vec!["md5".to_string(), "MD5".to_string()],
                },
            ],
            recommendation: "Replace with SHA-256 or SHA-3 immediately."
                .to_string(),
            cwe_id: Some("CWE-328".to_string()),
            migration_impacts: vec![],
        },
        // 3DES Rule
        Rule {
            id: "KYBER-007".to_string(),
            name: "Triple DES Encryption Detected".to_string(),
            description: "3DES provides only 112-bit security and is considered weak. Should be \
                replaced during PQC migration."
                .to_string(),
            vuln_type: VulnerabilityType::TripleDes,
            severity: Severity::Medium,
            patterns: vec![
                RulePattern::FunctionCall {
                    names: vec!["createCipheriv".to_string(), "createDecipheriv".to_string()],
                    module: None,
                },
                RulePattern::StringLiteral {
                    patterns: vec![
                        "des-ede3".to_string(),
                        "des-ede3-cbc".to_string(),
                        "3des".to_string(),
                        "triple-des".to_string(),
                        "DES3".to_string(),
                        "DESede".to_string(),
                    ],
                },
            ],
            recommendation: "Replace with AES-256-GCM for symmetric encryption."
                .to_string(),
            cwe_id: Some("CWE-327".to_string()),
            migration_impacts: vec![],
        },
        // DES Rule
        Rule {
            id: "KYBER-008".to_string(),
            name: "DES Encryption Detected".to_string(),
            description: "DES is broken and must not be used."
                .to_string(),
            vuln_type: VulnerabilityType::Des,
            severity: Severity::Critical,
            patterns: vec![
                RulePattern::StringLiteral {
                    patterns: vec![
                        "des-cbc".to_string(),
                        "des-ecb".to_string(),
                        "DES".to_string(),
                    ],
                },
            ],
            recommendation: "Replace with AES-256-GCM immediately."
                .to_string(),
            cwe_id: Some("CWE-327".to_string()),
            migration_impacts: vec![],
        },
        // RC4 Rule
        Rule {
            id: "KYBER-009".to_string(),
            name: "RC4 Stream Cipher Detected".to_string(),
            description: "RC4 is broken and must not be used."
                .to_string(),
            vuln_type: VulnerabilityType::Rc4,
            severity: Severity::Critical,
            patterns: vec![
                RulePattern::StringLiteral {
                    patterns: vec!["rc4".to_string(), "RC4".to_string(), "arcfour".to_string()],
                },
            ],
            recommendation: "Replace with AES-256-GCM or ChaCha20-Poly1305."
                .to_string(),
            cwe_id: Some("CWE-327".to_string()),
            migration_impacts: vec![],
        },
        // Weak Random Rule
        Rule {
            id: "KYBER-010".to_string(),
            name: "Weak Random Number Generator Detected".to_string(),
            description: "Using weak or predictable random number generators for cryptographic \
                purposes is dangerous."
                .to_string(),
            vuln_type: VulnerabilityType::WeakRandom,
            severity: Severity::High,
            patterns: vec![
                RulePattern::FunctionCall {
                    names: vec![
                        "Math.random".to_string(),
                        "random.random".to_string(),
                        "rand".to_string(),
                        "srand".to_string(),
                    ],
                    module: None,
                },
                RulePattern::MethodCall {
                    object_type: Some("Math".to_string()),
                    method_names: vec!["random".to_string()],
                },
            ],
            recommendation: "Use cryptographically secure random number generators: \
                crypto.randomBytes() in Node.js, secrets module in Python, crypto/rand in Go."
                .to_string(),
            cwe_id: Some("CWE-338".to_string()),
            migration_impacts: vec![],
        },
        // Insecure TLS Rule
        Rule {
            id: "KYBER-011".to_string(),
            name: "Insecure TLS Configuration Detected".to_string(),
            description: "TLS configurations using deprecated or weak protocols/ciphers."
                .to_string(),
            vuln_type: VulnerabilityType::InsecureTls,
            severity: Severity::High,
            patterns: vec![
                RulePattern::StringLiteral {
                    patterns: vec![
                        "TLSv1".to_string(),
                        "TLSv1.0".to_string(),
                        "TLSv1.1".to_string(),
                        "SSLv2".to_string(),
                        "SSLv3".to_string(),
                        "ssl2".to_string(),
                        "ssl3".to_string(),
                    ],
                },
            ],
            recommendation: "Use TLS 1.3 with PQC-ready cipher suites when available."
                .to_string(),
            cwe_id: Some("CWE-326".to_string()),
            migration_impacts: vec![MigrationImpactTemplate {
                impact_type: ImpactType::ProtocolChange,
                description: "TLS configuration must be updated to support PQC cipher suites."
                    .to_string(),
                estimated_effort: "Medium".to_string(),
                recommendation: "Prepare for TLS 1.3 with hybrid PQC cipher suites."
                    .to_string(),
            }],
        },
    ]
}

/// Rule for context-aware detection
pub trait CryptoRule {
    fn id(&self) -> &str;
    fn check(&self, context: &RuleContext) -> Option<RuleMatch>;
}

/// Context for rule checking
pub struct RuleContext<'a> {
    pub source_code: &'a str,
    pub file_path: &'a std::path::Path,
    pub language: crate::types::Language,
    pub line_number: usize,
    pub node_text: &'a str,
}

/// Result of a rule match
pub struct RuleMatch {
    pub rule_id: String,
    pub line: usize,
    pub column: usize,
    pub matched_text: String,
    pub context: String,
}
