use crate::error::{Result, SklearsError};

use super::security_types::*;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use chrono::{DateTime, Utc};
use std::collections::{HashMap, HashSet};
use std::time::Duration;

/// Advanced vulnerability database with CVE integration, OWASP mapping,
/// and custom vulnerability definitions.
///
/// # Features
///
/// - CVE (Common Vulnerabilities and Exposures) integration
/// - OWASP vulnerability mapping
/// - Custom vulnerability definitions
/// - Platform-specific vulnerability tracking
/// - Combination vulnerability detection
/// - Automated vulnerability updates
/// - Risk scoring and prioritization
/// - Historical vulnerability tracking
///
/// # Example
///
/// ```rust,ignore
/// use sklears_core::trait_explorer::security_analysis::VulnerabilityDatabase;
///
/// let mut db = VulnerabilityDatabase::new();
/// db.load_cve_database().expect("Failed to load CVE database");
///
/// if let Some(vulns) = db.get_vulnerabilities("Serialize") {
///     for vuln in vulns {
///         println!("Found vulnerability: {} - {}", vuln.id, vuln.description);
///     }
/// }
/// ```
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VulnerabilityDatabase {
    /// Known vulnerabilities mapped by trait name
    vulnerabilities: HashMap<String, Vec<SecurityVulnerability>>,

    /// CVE database integration
    cve_database: HashMap<String, CveEntry>,

    /// OWASP vulnerability mappings
    owasp_mappings: HashMap<String, Vec<String>>,

    /// Combination vulnerabilities (traits that are vulnerable when used together)
    combination_vulnerabilities: HashMap<Vec<String>, Vec<SecurityVulnerability>>,

    /// Platform-specific vulnerabilities
    platform_vulnerabilities: HashMap<String, HashMap<String, Vec<SecurityVulnerability>>>,

    /// Historical vulnerability data for trend analysis
    historical_vulnerabilities: Vec<HistoricalVulnerabilityData>,

    /// Vulnerability severity mappings
    severity_mappings: HashMap<String, RiskSeverity>,

    /// Custom vulnerability rules
    custom_rules: Vec<VulnerabilityRule>,

    /// Last update timestamp
    last_updated: DateTime<Utc>,

    /// Database configuration
    config: VulnerabilityDatabaseConfig,
}

impl VulnerabilityDatabase {
    /// Create a new vulnerability database.
    pub fn new() -> Self {
        let mut db = Self {
            vulnerabilities: HashMap::new(),
            cve_database: HashMap::new(),
            owasp_mappings: HashMap::new(),
            combination_vulnerabilities: HashMap::new(),
            platform_vulnerabilities: HashMap::new(),
            historical_vulnerabilities: Vec::new(),
            severity_mappings: HashMap::new(),
            custom_rules: Vec::new(),
            last_updated: Utc::now(),
            config: VulnerabilityDatabaseConfig::default(),
        };

        db.initialize_default_vulnerabilities();
        db.initialize_owasp_mappings();
        db.initialize_severity_mappings();
        db
    }

    /// Create a new vulnerability database with custom configuration.
    pub fn with_config(config: VulnerabilityDatabaseConfig) -> Self {
        let mut db = Self::new();
        db.config = config;
        db
    }

    /// Load CVE database from external source.
    pub fn load_cve_database(&mut self) -> Result<()> {
        // In a real implementation, this would fetch from the National Vulnerability Database
        // For now, we'll initialize with some example CVE entries
        self.initialize_sample_cve_data();
        self.last_updated = Utc::now();
        Ok(())
    }

    /// Update vulnerability database from external sources.
    pub async fn update_database(&mut self) -> Result<()> {
        // In a real implementation, this would:
        // 1. Fetch latest CVE data from NVD
        // 2. Update OWASP mappings
        // 3. Sync with security advisory databases
        // 4. Update platform-specific vulnerabilities

        self.last_updated = Utc::now();
        Ok(())
    }

    /// Get vulnerabilities for a specific trait.
    pub fn get_vulnerabilities(&self, trait_name: &str) -> Option<Vec<SecurityVulnerability>> {
        self.vulnerabilities.get(trait_name).cloned()
    }

    /// Get combination vulnerabilities for a set of traits.
    pub fn get_combination_vulnerabilities(
        &self,
        traits: &[String],
    ) -> Option<Vec<SecurityVulnerability>> {
        let mut sorted_traits = traits.to_vec();
        sorted_traits.sort();
        self.combination_vulnerabilities
            .get(&sorted_traits)
            .cloned()
    }

    /// Get platform-specific vulnerabilities.
    pub fn get_platform_vulnerabilities(
        &self,
        platform: &str,
        trait_name: &str,
    ) -> Option<Vec<SecurityVulnerability>> {
        self.platform_vulnerabilities
            .get(platform)?
            .get(trait_name)
            .cloned()
    }

    /// Search vulnerabilities by keyword.
    pub fn search_vulnerabilities(&self, keyword: &str) -> Vec<SecurityVulnerability> {
        let mut results = Vec::new();
        let keyword_lower = keyword.to_lowercase();

        for vulns in self.vulnerabilities.values() {
            for vuln in vulns {
                if vuln.description.to_lowercase().contains(&keyword_lower)
                    || vuln.category.to_lowercase().contains(&keyword_lower)
                    || vuln.id.to_lowercase().contains(&keyword_lower)
                {
                    results.push(vuln.clone());
                }
            }
        }

        results
    }

    /// Get vulnerabilities by severity level.
    pub fn get_vulnerabilities_by_severity(&self, severity: &RiskSeverity) -> Vec<SecurityVulnerability> {
        let mut results = Vec::new();

        for vulns in self.vulnerabilities.values() {
            for vuln in vulns {
                if &vuln.severity == severity {
                    results.push(vuln.clone());
                }
            }
        }

        results
    }

    /// Get vulnerabilities by category.
    pub fn get_vulnerabilities_by_category(&self, category: &str) -> Vec<SecurityVulnerability> {
        let mut results = Vec::new();

        for vulns in self.vulnerabilities.values() {
            for vuln in vulns {
                if vuln.category.eq_ignore_ascii_case(category) {
                    results.push(vuln.clone());
                }
            }
        }

        results
    }

    /// Get CVE entry by ID.
    pub fn get_cve_entry(&self, cve_id: &str) -> Option<&CveEntry> {
        self.cve_database.get(cve_id)
    }

    /// Get all CVE entries.
    pub fn get_all_cve_entries(&self) -> Vec<&CveEntry> {
        self.cve_database.values().collect()
    }

    /// Get OWASP mappings for a category.
    pub fn get_owasp_mappings(&self, category: &str) -> Option<&Vec<String>> {
        self.owasp_mappings.get(category)
    }

    /// Add a custom vulnerability to the database.
    pub fn add_vulnerability(&mut self, trait_name: String, vulnerability: SecurityVulnerability) {
        self.vulnerabilities
            .entry(trait_name)
            .or_insert_with(Vec::new)
            .push(vulnerability);
        self.last_updated = Utc::now();
    }

    /// Add a combination vulnerability.
    pub fn add_combination_vulnerability(
        &mut self,
        trait_combination: Vec<String>,
        vulnerability: SecurityVulnerability,
    ) {
        let mut sorted_traits = trait_combination;
        sorted_traits.sort();
        self.combination_vulnerabilities
            .entry(sorted_traits)
            .or_insert_with(Vec::new)
            .push(vulnerability);
        self.last_updated = Utc::now();
    }

    /// Add a platform-specific vulnerability.
    pub fn add_platform_vulnerability(
        &mut self,
        platform: String,
        trait_name: String,
        vulnerability: SecurityVulnerability,
    ) {
        self.platform_vulnerabilities
            .entry(platform)
            .or_insert_with(HashMap::new)
            .entry(trait_name)
            .or_insert_with(Vec::new)
            .push(vulnerability);
        self.last_updated = Utc::now();
    }

    /// Add a CVE entry to the database.
    pub fn add_cve_entry(&mut self, cve_entry: CveEntry) {
        self.cve_database.insert(cve_entry.id.clone(), cve_entry);
        self.last_updated = Utc::now();
    }

    /// Add a custom vulnerability rule.
    pub fn add_custom_rule(&mut self, rule: VulnerabilityRule) {
        self.custom_rules.push(rule);
        self.last_updated = Utc::now();
    }

    /// Evaluate custom vulnerability rules against a trait usage context.
    pub fn evaluate_custom_rules(&self, context: &TraitUsageContext) -> Vec<SecurityVulnerability> {
        let mut vulnerabilities = Vec::new();

        for rule in &self.custom_rules {
            if rule.evaluate(context) {
                vulnerabilities.push(rule.generate_vulnerability(context));
            }
        }

        vulnerabilities
    }

    /// Get vulnerability statistics.
    pub fn get_statistics(&self) -> VulnerabilityStatistics {
        let total_vulnerabilities: usize = self.vulnerabilities.values().map(|v| v.len()).sum();
        let total_cve_entries = self.cve_database.len();
        let total_combination_vulnerabilities: usize = self
            .combination_vulnerabilities
            .values()
            .map(|v| v.len())
            .sum();

        let mut severity_distribution = HashMap::new();
        for vulns in self.vulnerabilities.values() {
            for vuln in vulns {
                *severity_distribution.entry(vuln.severity.clone()).or_insert(0) += 1;
            }
        }

        let mut category_distribution = HashMap::new();
        for vulns in self.vulnerabilities.values() {
            for vuln in vulns {
                *category_distribution.entry(vuln.category.clone()).or_insert(0) += 1;
            }
        }

        let unique_traits = self.vulnerabilities.keys().len();
        let unique_platforms = self.platform_vulnerabilities.keys().len();

        VulnerabilityStatistics {
            total_vulnerabilities,
            total_cve_entries,
            total_combination_vulnerabilities,
            severity_distribution,
            category_distribution,
            unique_traits,
            unique_platforms,
            last_updated: self.last_updated,
        }
    }

    /// Get vulnerabilities discovered in a time range.
    pub fn get_vulnerabilities_in_range(
        &self,
        start: DateTime<Utc>,
        end: DateTime<Utc>,
    ) -> Vec<SecurityVulnerability> {
        let mut results = Vec::new();

        for vulns in self.vulnerabilities.values() {
            for vuln in vulns {
                if vuln.discovery_date >= start && vuln.discovery_date <= end {
                    results.push(vuln.clone());
                }
            }
        }

        results
    }

    /// Export vulnerability database to external format.
    pub fn export_database(&self, format: ExportFormat) -> Result<String> {
        match format {
            ExportFormat::Json => {
                #[cfg(feature = "serde")]
                {
                    serde_json::to_string_pretty(self)
                        .map_err(|e| SklearsError::General(format!("Serialization error: {}", e)))
                }
                #[cfg(not(feature = "serde"))]
                {
                    Err(SklearsError::General("JSON export requires serde feature".to_string()))
                }
            }
            ExportFormat::Csv => {
                let mut csv_data = String::new();
                csv_data.push_str("trait_name,vulnerability_id,category,severity,description,cvss_score\n");

                for (trait_name, vulns) in &self.vulnerabilities {
                    for vuln in vulns {
                        csv_data.push_str(&format!(
                            "{},{},{},{:?},{},{}\n",
                            trait_name,
                            vuln.id,
                            vuln.category,
                            vuln.severity,
                            vuln.description.replace(',', ";"),
                            vuln.cvss_score.unwrap_or(0.0)
                        ));
                    }
                }

                Ok(csv_data)
            }
            ExportFormat::Xml => {
                let mut xml_data = String::new();
                xml_data.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
                xml_data.push_str("<vulnerability_database>\n");

                for (trait_name, vulns) in &self.vulnerabilities {
                    xml_data.push_str(&format!("  <trait name=\"{}\">\n", trait_name));
                    for vuln in vulns {
                        xml_data.push_str("    <vulnerability>\n");
                        xml_data.push_str(&format!("      <id>{}</id>\n", vuln.id));
                        xml_data.push_str(&format!("      <category>{}</category>\n", vuln.category));
                        xml_data.push_str(&format!("      <severity>{:?}</severity>\n", vuln.severity));
                        xml_data.push_str(&format!("      <description>{}</description>\n", vuln.description));
                        xml_data.push_str(&format!("      <cvss_score>{}</cvss_score>\n", vuln.cvss_score.unwrap_or(0.0)));
                        xml_data.push_str("    </vulnerability>\n");
                    }
                    xml_data.push_str("  </trait>\n");
                }

                xml_data.push_str("</vulnerability_database>\n");
                Ok(xml_data)
            }
        }
    }

    /// Import vulnerability database from external format.
    pub fn import_database(&mut self, data: &str, format: ImportFormat) -> Result<()> {
        match format {
            ImportFormat::Json => {
                #[cfg(feature = "serde")]
                {
                    let imported: VulnerabilityDatabase = serde_json::from_str(data)
                        .map_err(|e| SklearsError::General(format!("Deserialization error: {}", e)))?;

                    // Merge imported data
                    for (trait_name, vulns) in imported.vulnerabilities {
                        for vuln in vulns {
                            self.add_vulnerability(trait_name.clone(), vuln);
                        }
                    }

                    for (cve_id, cve_entry) in imported.cve_database {
                        self.cve_database.insert(cve_id, cve_entry);
                    }

                    Ok(())
                }
                #[cfg(not(feature = "serde"))]
                {
                    Err(SklearsError::General("JSON import requires serde feature".to_string()))
                }
            }
            ImportFormat::Csv => {
                // Simple CSV parsing implementation
                let lines: Vec<&str> = data.lines().collect();
                if lines.is_empty() {
                    return Ok(());
                }

                // Skip header line
                for line in lines.iter().skip(1) {
                    let fields: Vec<&str> = line.split(',').collect();
                    if fields.len() >= 6 {
                        let trait_name = fields[0].to_string();
                        let vuln_id = fields[1].to_string();
                        let category = fields[2].to_string();
                        let severity = match fields[3] {
                            "Critical" => RiskSeverity::Critical,
                            "High" => RiskSeverity::High,
                            "Medium" => RiskSeverity::Medium,
                            _ => RiskSeverity::Low,
                        };
                        let description = fields[4].replace(';', ",");
                        let cvss_score = fields[5].parse::<f64>().ok();

                        let vulnerability = SecurityVulnerability {
                            id: vuln_id,
                            category,
                            severity,
                            description,
                            mitigation: "Custom mitigation required".to_string(),
                            fix_complexity: ImplementationEffort::Medium,
                            cve_references: Vec::new(),
                            owasp_references: Vec::new(),
                            affected_platforms: vec!["All".to_string()],
                            discovery_date: Utc::now(),
                            cvss_score,
                        };

                        self.add_vulnerability(trait_name, vulnerability);
                    }
                }

                Ok(())
            }
        }
    }

    /// Clean up old vulnerability data based on retention policy.
    pub fn cleanup_old_data(&mut self) {
        if let Some(retention_period) = self.config.data_retention_period {
            let cutoff_date = Utc::now() - retention_period;

            // Clean up historical vulnerability data
            self.historical_vulnerabilities.retain(|data| data.timestamp > cutoff_date);

            // Optionally clean up old CVE entries
            if self.config.cleanup_old_cve_entries {
                self.cve_database.retain(|_, entry| entry.last_modified > cutoff_date);
            }
        }
    }

    /// Initialize default vulnerabilities for common traits.
    fn initialize_default_vulnerabilities(&mut self) {
        // Serialize/Deserialize vulnerabilities
        self.add_vulnerability(
            "Serialize".to_string(),
            SecurityVulnerability {
                id: "SKLEARS-001".to_string(),
                category: "Serialization".to_string(),
                severity: RiskSeverity::Medium,
                description: "Potential for malicious data injection through deserialization"
                    .to_string(),
                mitigation: "Implement strict input validation and use safe serialization formats"
                    .to_string(),
                fix_complexity: ImplementationEffort::Medium,
                cve_references: vec!["CVE-2019-12384".to_string()],
                owasp_references: vec![
                    "A08:2021 – Software and Data Integrity Failures".to_string()
                ],
                affected_platforms: vec!["All".to_string()],
                discovery_date: Utc::now(),
                cvss_score: Some(6.1),
            },
        );

        // Clone vulnerabilities
        self.add_vulnerability(
            "Clone".to_string(),
            SecurityVulnerability {
                id: "SKLEARS-002".to_string(),
                category: "Memory Safety".to_string(),
                severity: RiskSeverity::Low,
                description: "Deep cloning may expose sensitive data in memory".to_string(),
                mitigation: "Use secure memory allocation and clearing for sensitive data"
                    .to_string(),
                fix_complexity: ImplementationEffort::Low,
                cve_references: Vec::new(),
                owasp_references: vec!["A02:2021 – Cryptographic Failures".to_string()],
                affected_platforms: vec!["All".to_string()],
                discovery_date: Utc::now(),
                cvss_score: Some(3.1),
            },
        );

        // Send/Sync vulnerabilities for concurrency
        let send_sync_vuln = SecurityVulnerability {
            id: "SKLEARS-003".to_string(),
            category: "Concurrency".to_string(),
            severity: RiskSeverity::Medium,
            description: "Race conditions in concurrent access to shared data".to_string(),
            mitigation: "Use proper synchronization primitives and memory ordering".to_string(),
            fix_complexity: ImplementationEffort::High,
            cve_references: Vec::new(),
            owasp_references: vec!["A04:2021 – Insecure Design".to_string()],
            affected_platforms: vec!["All".to_string()],
            discovery_date: Utc::now(),
            cvss_score: Some(5.3),
        };

        self.add_vulnerability("Send".to_string(), send_sync_vuln.clone());
        self.add_vulnerability("Sync".to_string(), send_sync_vuln);

        // Debug trait vulnerability
        self.add_vulnerability(
            "Debug".to_string(),
            SecurityVulnerability {
                id: "SKLEARS-004".to_string(),
                category: "Information Disclosure".to_string(),
                severity: RiskSeverity::Low,
                description: "Debug output may leak sensitive information".to_string(),
                mitigation: "Implement custom Debug implementations that redact sensitive data"
                    .to_string(),
                fix_complexity: ImplementationEffort::Low,
                cve_references: Vec::new(),
                owasp_references: vec!["A09:2021 – Security Logging and Monitoring Failures".to_string()],
                affected_platforms: vec!["All".to_string()],
                discovery_date: Utc::now(),
                cvss_score: Some(2.1),
            },
        );

        // Drop trait vulnerability
        self.add_vulnerability(
            "Drop".to_string(),
            SecurityVulnerability {
                id: "SKLEARS-005".to_string(),
                category: "Resource Management".to_string(),
                severity: RiskSeverity::Medium,
                description: "Improper resource cleanup in Drop implementation".to_string(),
                mitigation: "Ensure proper resource cleanup and consider security implications"
                    .to_string(),
                fix_complexity: ImplementationEffort::Medium,
                cve_references: Vec::new(),
                owasp_references: vec!["A06:2021 – Vulnerable and Outdated Components".to_string()],
                affected_platforms: vec!["All".to_string()],
                discovery_date: Utc::now(),
                cvss_score: Some(4.3),
            },
        );

        // Initialize combination vulnerabilities
        self.initialize_combination_vulnerabilities();
    }

    /// Initialize combination vulnerabilities.
    fn initialize_combination_vulnerabilities(&mut self) {
        // Serialize + Clone combination vulnerability
        self.add_combination_vulnerability(
            vec!["Serialize".to_string(), "Clone".to_string()],
            SecurityVulnerability {
                id: "SKLEARS-COMBO-001".to_string(),
                category: "Serialization + Cloning".to_string(),
                severity: RiskSeverity::High,
                description: "Combined serialization and cloning creates double exposure risk"
                    .to_string(),
                mitigation: "Implement secure serialization with non-cloneable sensitive data"
                    .to_string(),
                fix_complexity: ImplementationEffort::High,
                cve_references: Vec::new(),
                owasp_references: vec!["A08:2021 – Software and Data Integrity Failures".to_string()],
                affected_platforms: vec!["All".to_string()],
                discovery_date: Utc::now(),
                cvss_score: Some(7.1),
            },
        );

        // Send + Sync + Clone combination vulnerability
        self.add_combination_vulnerability(
            vec!["Send".to_string(), "Sync".to_string(), "Clone".to_string()],
            SecurityVulnerability {
                id: "SKLEARS-COMBO-002".to_string(),
                category: "Concurrent Cloning".to_string(),
                severity: RiskSeverity::Medium,
                description: "Concurrent cloning of shared data creates race conditions"
                    .to_string(),
                mitigation: "Use atomic operations or proper locking for concurrent cloning"
                    .to_string(),
                fix_complexity: ImplementationEffort::High,
                cve_references: Vec::new(),
                owasp_references: vec!["A04:2021 – Insecure Design".to_string()],
                affected_platforms: vec!["All".to_string()],
                discovery_date: Utc::now(),
                cvss_score: Some(5.8),
            },
        );
    }

    /// Initialize sample CVE data.
    fn initialize_sample_cve_data(&mut self) {
        self.cve_database.insert(
            "CVE-2019-12384".to_string(),
            CveEntry {
                id: "CVE-2019-12384".to_string(),
                description: "Deserialization of untrusted data vulnerability".to_string(),
                cvss_score: 6.1,
                severity: "Medium".to_string(),
                published_date: DateTime::parse_from_rfc3339("2019-06-01T00:00:00Z")
                    .expect("expected valid value")
                    .with_timezone(&Utc),
                last_modified: DateTime::parse_from_rfc3339("2019-06-15T00:00:00Z")
                    .expect("expected valid value")
                    .with_timezone(&Utc),
                references: vec!["https://nvd.nist.gov/vuln/detail/CVE-2019-12384".to_string()],
            },
        );

        self.cve_database.insert(
            "CVE-2020-15005".to_string(),
            CveEntry {
                id: "CVE-2020-15005".to_string(),
                description: "Race condition in concurrent data access".to_string(),
                cvss_score: 5.3,
                severity: "Medium".to_string(),
                published_date: DateTime::parse_from_rfc3339("2020-07-01T00:00:00Z")
                    .expect("expected valid value")
                    .with_timezone(&Utc),
                last_modified: DateTime::parse_from_rfc3339("2020-07-10T00:00:00Z")
                    .expect("expected valid value")
                    .with_timezone(&Utc),
                references: vec!["https://nvd.nist.gov/vuln/detail/CVE-2020-15005".to_string()],
            },
        );
    }

    /// Initialize OWASP mappings.
    fn initialize_owasp_mappings(&mut self) {
        self.owasp_mappings.insert(
            "Injection".to_string(),
            vec!["A03:2021 – Injection".to_string()],
        );

        self.owasp_mappings.insert(
            "Serialization".to_string(),
            vec!["A08:2021 – Software and Data Integrity Failures".to_string()],
        );

        self.owasp_mappings.insert(
            "Memory Safety".to_string(),
            vec!["A02:2021 – Cryptographic Failures".to_string()],
        );

        self.owasp_mappings.insert(
            "Concurrency".to_string(),
            vec!["A04:2021 – Insecure Design".to_string()],
        );

        self.owasp_mappings.insert(
            "Information Disclosure".to_string(),
            vec!["A09:2021 – Security Logging and Monitoring Failures".to_string()],
        );
    }

    /// Initialize severity mappings.
    fn initialize_severity_mappings(&mut self) {
        self.severity_mappings.insert("Critical".to_string(), RiskSeverity::Critical);
        self.severity_mappings.insert("High".to_string(), RiskSeverity::High);
        self.severity_mappings.insert("Medium".to_string(), RiskSeverity::Medium);
        self.severity_mappings.insert("Low".to_string(), RiskSeverity::Low);
    }

    /// Get database configuration.
    pub fn get_config(&self) -> &VulnerabilityDatabaseConfig {
        &self.config
    }

    /// Update database configuration.
    pub fn update_config(&mut self, config: VulnerabilityDatabaseConfig) {
        self.config = config;
    }

    /// Get last update timestamp.
    pub fn get_last_updated(&self) -> DateTime<Utc> {
        self.last_updated
    }

    /// Get the number of vulnerabilities in the database.
    pub fn vulnerability_count(&self) -> usize {
        self.vulnerabilities.values().map(|v| v.len()).sum()
    }

    /// Get the number of CVE entries in the database.
    pub fn cve_count(&self) -> usize {
        self.cve_database.len()
    }
}

impl Default for VulnerabilityDatabase {
    fn default() -> Self {
        Self::new()
    }
}

/// CVE database entry.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CveEntry {
    /// CVE identifier
    pub id: String,

    /// CVE description
    pub description: String,

    /// CVSS score
    pub cvss_score: f64,

    /// Severity rating
    pub severity: String,

    /// Publication date
    pub published_date: DateTime<Utc>,

    /// Last modified date
    pub last_modified: DateTime<Utc>,

    /// Reference URLs
    pub references: Vec<String>,
}

/// Historical vulnerability data for trend analysis.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct HistoricalVulnerabilityData {
    /// Timestamp of the vulnerability data
    pub timestamp: DateTime<Utc>,

    /// Vulnerability identifier
    pub vulnerability_id: String,

    /// Severity at that time
    pub severity: RiskSeverity,

    /// CVSS score at that time
    pub cvss_score: Option<f64>,

    /// Status of the vulnerability
    pub status: VulnerabilityStatus,
}

/// Vulnerability status enumeration.
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum VulnerabilityStatus {
    Active,
    Patched,
    Mitigated,
    Deprecated,
    UnderReview,
}

/// Custom vulnerability rule for dynamic vulnerability detection.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VulnerabilityRule {
    /// Rule identifier
    pub id: String,

    /// Rule name
    pub name: String,

    /// Rule description
    pub description: String,

    /// Conditions for rule evaluation
    pub conditions: Vec<RuleCondition>,

    /// Vulnerability template to generate when rule matches
    pub vulnerability_template: VulnerabilityTemplate,
}

impl VulnerabilityRule {
    /// Evaluate the rule against a trait usage context.
    pub fn evaluate(&self, context: &TraitUsageContext) -> bool {
        self.conditions.iter().all(|condition| condition.evaluate(context))
    }

    /// Generate a vulnerability based on the template and context.
    pub fn generate_vulnerability(&self, context: &TraitUsageContext) -> SecurityVulnerability {
        self.vulnerability_template.generate_vulnerability(context)
    }
}

/// Rule condition for vulnerability detection.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct RuleCondition {
    /// Condition type
    pub condition_type: ConditionType,

    /// Condition value
    pub condition_value: String,

    /// Whether the condition should be negated
    pub negate: bool,
}

impl RuleCondition {
    /// Evaluate the condition against a trait usage context.
    pub fn evaluate(&self, context: &TraitUsageContext) -> bool {
        let result = match &self.condition_type {
            ConditionType::TraitPresent => {
                context.traits.contains(&self.condition_value)
            }
            ConditionType::PropertyTrue => {
                match self.condition_value.as_str() {
                    "handles_sensitive_data" => context.handles_sensitive_data,
                    "has_input_validation" => context.has_input_validation,
                    "has_encryption" => context.has_encryption,
                    "has_audit_logging" => context.has_audit_logging,
                    "has_access_controls" => context.has_access_controls,
                    "has_rate_limiting" => context.has_rate_limiting,
                    "has_bounds_checking" => context.has_bounds_checking,
                    _ => false,
                }
            }
            ConditionType::PropertyFalse => {
                match self.condition_value.as_str() {
                    "handles_sensitive_data" => !context.handles_sensitive_data,
                    "has_input_validation" => !context.has_input_validation,
                    "has_encryption" => !context.has_encryption,
                    "has_audit_logging" => !context.has_audit_logging,
                    "has_access_controls" => !context.has_access_controls,
                    "has_rate_limiting" => !context.has_rate_limiting,
                    "has_bounds_checking" => !context.has_bounds_checking,
                    _ => false,
                }
            }
            ConditionType::TraitCombination => {
                let required_traits: Vec<&str> = self.condition_value.split(',').collect();
                required_traits.iter().all(|trait_name| {
                    context.traits.contains(&trait_name.trim().to_string())
                })
            }
        };

        if self.negate { !result } else { result }
    }
}

/// Condition types for vulnerability rules.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ConditionType {
    TraitPresent,
    PropertyTrue,
    PropertyFalse,
    TraitCombination,
}

/// Vulnerability template for generating vulnerabilities from rules.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VulnerabilityTemplate {
    /// Template ID
    pub id_template: String,

    /// Template category
    pub category: String,

    /// Template severity
    pub severity: RiskSeverity,

    /// Template description
    pub description_template: String,

    /// Template mitigation
    pub mitigation_template: String,

    /// Template fix complexity
    pub fix_complexity: ImplementationEffort,

    /// Template OWASP references
    pub owasp_references: Vec<String>,

    /// Template CVSS score
    pub cvss_score: Option<f64>,
}

impl VulnerabilityTemplate {
    /// Generate a vulnerability from the template and context.
    pub fn generate_vulnerability(&self, context: &TraitUsageContext) -> SecurityVulnerability {
        let traits_str = context.traits.join(", ");

        SecurityVulnerability {
            id: self.id_template.replace("{traits}", &traits_str),
            category: self.category.clone(),
            severity: self.severity.clone(),
            description: self.description_template.replace("{traits}", &traits_str),
            mitigation: self.mitigation_template.replace("{traits}", &traits_str),
            fix_complexity: self.fix_complexity.clone(),
            cve_references: Vec::new(),
            owasp_references: self.owasp_references.clone(),
            affected_platforms: vec!["All".to_string()],
            discovery_date: Utc::now(),
            cvss_score: self.cvss_score,
        }
    }
}

/// Vulnerability database configuration.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VulnerabilityDatabaseConfig {
    /// Enable automatic updates
    pub auto_update: bool,

    /// Update frequency
    pub update_frequency: Duration,

    /// Data retention period
    pub data_retention_period: Option<Duration>,

    /// Enable CVE integration
    pub enable_cve_integration: bool,

    /// Enable OWASP integration
    pub enable_owasp_integration: bool,

    /// Clean up old CVE entries
    pub cleanup_old_cve_entries: bool,

    /// Maximum number of vulnerabilities per trait
    pub max_vulnerabilities_per_trait: Option<usize>,

    /// Cache size for vulnerability queries
    pub cache_size: usize,
}

impl Default for VulnerabilityDatabaseConfig {
    fn default() -> Self {
        Self {
            auto_update: false,
            update_frequency: Duration::from_secs(86400), // 24 hours
            data_retention_period: Some(Duration::from_secs(86400 * 365)), // 1 year
            enable_cve_integration: true,
            enable_owasp_integration: true,
            cleanup_old_cve_entries: false,
            max_vulnerabilities_per_trait: Some(100),
            cache_size: 1000,
        }
    }
}

/// Vulnerability database statistics.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct VulnerabilityStatistics {
    /// Total number of vulnerabilities
    pub total_vulnerabilities: usize,

    /// Total number of CVE entries
    pub total_cve_entries: usize,

    /// Total number of combination vulnerabilities
    pub total_combination_vulnerabilities: usize,

    /// Distribution by severity
    pub severity_distribution: HashMap<RiskSeverity, usize>,

    /// Distribution by category
    pub category_distribution: HashMap<String, usize>,

    /// Number of unique traits covered
    pub unique_traits: usize,

    /// Number of unique platforms covered
    pub unique_platforms: usize,

    /// Last update timestamp
    pub last_updated: DateTime<Utc>,
}

/// Export formats for vulnerability database.
#[derive(Debug, Clone)]
pub enum ExportFormat {
    Json,
    Csv,
    Xml,
}

/// Import formats for vulnerability database.
#[derive(Debug, Clone)]
pub enum ImportFormat {
    Json,
    Csv,
}

#[allow(non_snake_case)]
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_vulnerability_database_creation() {
        let db = VulnerabilityDatabase::new();
        assert!(db.vulnerability_count() > 0);
        assert!(db.cve_count() > 0);
    }

    #[test]
    fn test_get_vulnerabilities() {
        let db = VulnerabilityDatabase::new();
        let vulns = db.get_vulnerabilities("Serialize");
        assert!(vulns.is_some());
        assert!(!vulns.expect("expected valid value").is_empty());
    }

    #[test]
    fn test_search_vulnerabilities() {
        let db = VulnerabilityDatabase::new();
        let results = db.search_vulnerabilities("serialization");
        assert!(!results.is_empty());
    }

    #[test]
    fn test_vulnerability_statistics() {
        let db = VulnerabilityDatabase::new();
        let stats = db.get_statistics();
        assert!(stats.total_vulnerabilities > 0);
        assert!(stats.unique_traits > 0);
    }

    #[test]
    fn test_custom_vulnerability_rule() {
        let rule = VulnerabilityRule {
            id: "TEST-001".to_string(),
            name: "Test Rule".to_string(),
            description: "Test rule for serialization without validation".to_string(),
            conditions: vec![
                RuleCondition {
                    condition_type: ConditionType::TraitPresent,
                    condition_value: "Serialize".to_string(),
                    negate: false,
                },
                RuleCondition {
                    condition_type: ConditionType::PropertyFalse,
                    condition_value: "has_input_validation".to_string(),
                    negate: false,
                },
            ],
            vulnerability_template: VulnerabilityTemplate {
                id_template: "CUSTOM-{traits}".to_string(),
                category: "Test Category".to_string(),
                severity: RiskSeverity::Medium,
                description_template: "Test vulnerability for {traits}".to_string(),
                mitigation_template: "Implement proper validation for {traits}".to_string(),
                fix_complexity: ImplementationEffort::Low,
                owasp_references: vec!["A03:2021 – Injection".to_string()],
                cvss_score: Some(5.0),
            },
        };

        let context = TraitUsageContext {
            traits: vec!["Serialize".to_string()],
            has_input_validation: false,
            ..Default::default()
        };

        assert!(rule.evaluate(&context));
        let vuln = rule.generate_vulnerability(&context);
        assert_eq!(vuln.category, "Test Category");
    }
}