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

pub mod crypto_rules;
pub mod dependency_rules;

pub use crypto_rules::CryptoRule;
pub use dependency_rules::DependencyRule;

/// A rule definition for detecting vulnerabilities
#[derive(Debug, Clone)]
pub struct Rule {
    pub id: String,
    pub name: String,
    pub description: String,
    pub vuln_type: VulnerabilityType,
    pub severity: Severity,
    pub patterns: Vec<RulePattern>,
    pub recommendation: String,
    pub cwe_id: Option<String>,
    pub migration_impacts: Vec<MigrationImpactTemplate>,
}

/// Pattern types for matching
#[derive(Debug, Clone)]
pub enum RulePattern {
    /// Match a function call
    FunctionCall {
        names: Vec<String>,
        module: Option<String>,
    },
    /// Match an import statement
    Import {
        modules: Vec<String>,
        symbols: Vec<String>,
    },
    /// Match a method call on an object
    MethodCall {
        object_type: Option<String>,
        method_names: Vec<String>,
    },
    /// Match a string literal pattern
    StringLiteral {
        patterns: Vec<String>,
    },
    /// Regex pattern
    Regex {
        pattern: String,
    },
    /// AST node type with specific properties
    AstNode {
        node_type: String,
        properties: Vec<(String, String)>,
    },
}

/// Template for migration impact
#[derive(Debug, Clone)]
pub struct MigrationImpactTemplate {
    pub impact_type: ImpactType,
    pub description: String,
    pub estimated_effort: String,
    pub recommendation: String,
}

impl MigrationImpactTemplate {
    pub fn to_impact(&self, affected_components: Vec<String>) -> MigrationImpact {
        MigrationImpact {
            impact_type: self.impact_type.clone(),
            description: self.description.clone(),
            affected_components,
            estimated_effort: self.estimated_effort.clone(),
            recommendation: self.recommendation.clone(),
        }
    }
}

/// Get all built-in rules
pub fn get_all_rules() -> Vec<Rule> {
    let mut rules = Vec::new();
    rules.extend(crypto_rules::get_crypto_rules());
    rules.extend(dependency_rules::get_dependency_rules());
    rules
}

/// Get rules filtered by language
pub fn get_rules_for_language(language: &crate::types::Language) -> Vec<Rule> {
    // All rules apply to all languages for now
    // In the future, we can add language-specific filtering
    get_all_rules()
}
