//! # Security Testing Framework
//!
//! This module provides security testing capabilities for `SciRS2` Core,
//! focusing on input validation, bounds checking, and vulnerability discovery.
//! It includes:
//! - Input validation testing
//! - Buffer overflow detection
//! - Integer overflow testing
//! - Memory safety verification
//! - Denial of service attack simulation

use crate::error::{CoreError, CoreResult, ErrorContext};
use crate::testing::{TestConfig, TestResult};
use std::time::{Duration, Instant};

/// Security test configuration
#[derive(Debug, Clone)]
pub struct SecurityTestConfig {
    /// Maximum input size to test
    pub max_input_size: usize,
    /// Number of malicious input patterns to test
    pub malicious_patterns: usize,
    /// Enable bounds checking tests
    pub test_bounds_checking: bool,
    /// Enable integer overflow tests
    pub test_integer_overflow: bool,
    /// Enable memory safety tests
    pub test_memory_safety: bool,
    /// Enable DoS simulation tests
    pub test_dos_simulation: bool,
    /// Timeout for individual security tests
    pub test_timeout: Duration,
}

impl Default for SecurityTestConfig {
    fn default() -> Self {
        Self {
            max_input_size: 1024 * 1024, // 1MB
            malicious_patterns: 1000,
            test_bounds_checking: true,
            test_integer_overflow: true,
            test_memory_safety: true,
            test_dos_simulation: true,
            test_timeout: Duration::from_secs(10),
        }
    }
}

impl SecurityTestConfig {
    /// Create a new security test configuration
    pub fn new() -> Self {
        Self::default()
    }

    /// Set the maximum input size
    pub fn with_max_input_size(mut self, size: usize) -> Self {
        self.max_input_size = size;
        self
    }

    /// Set the number of malicious patterns
    pub fn with_malicious_patterns(mut self, patterns: usize) -> Self {
        self.malicious_patterns = patterns;
        self
    }

    /// Enable or disable bounds checking tests
    pub fn with_bounds_checking(mut self, enabled: bool) -> Self {
        self.test_bounds_checking = enabled;
        self
    }

    /// Enable or disable integer overflow tests
    pub fn with_integer_overflow(mut self, enabled: bool) -> Self {
        self.test_integer_overflow = enabled;
        self
    }

    /// Enable or disable memory safety tests
    pub fn with_memory_safety(mut self, enabled: bool) -> Self {
        self.test_memory_safety = enabled;
        self
    }

    /// Enable or disable DoS simulation tests
    pub fn with_dos_simulation(mut self, enabled: bool) -> Self {
        self.test_dos_simulation = enabled;
        self
    }

    /// Set the test timeout
    pub fn with_test_timeout(mut self, timeout: Duration) -> Self {
        self.test_timeout = timeout;
        self
    }
}

/// Security test result
#[derive(Debug, Clone)]
pub struct SecurityTestResult {
    /// Test name
    pub test_name: String,
    /// Number of tests executed
    pub tests_executed: usize,
    /// Number of vulnerabilities found
    pub vulnerabilities_found: usize,
    /// Test execution time
    pub duration: Duration,
    /// Security issues discovered
    pub security_issues: Vec<SecurityIssue>,
    /// Overall security assessment
    pub security_level: SecurityLevel,
}

/// Security issue found during testing
#[derive(Debug, Clone)]
pub struct SecurityIssue {
    /// Issue severity
    pub severity: SecuritySeverity,
    /// Issue category
    pub category: SecurityCategory,
    /// Description of the issue
    pub description: String,
    /// Input that triggered the issue
    pub trigger_input: String,
    /// Recommended mitigation
    pub mitigation: Option<String>,
}

/// Security severity levels
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SecuritySeverity {
    /// Critical security vulnerability
    Critical,
    /// High severity issue
    High,
    /// Medium severity issue
    Medium,
    /// Low severity issue
    Low,
    /// Informational finding
    Info,
}

/// Security issue categories
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SecurityCategory {
    /// Buffer overflow or underflow
    BufferOverflow,
    /// Integer overflow or underflow
    IntegerOverflow,
    /// Out-of-bounds access
    OutOfBounds,
    /// Memory safety violation
    MemorySafety,
    /// Input validation bypass
    InputValidation,
    /// Denial of service vulnerability
    DenialOfService,
    /// Information disclosure
    InformationDisclosure,
    /// Dependency vulnerability
    DependencyVuln,
    /// Configuration security issue
    ConfigSecurity,
    /// Third-party integration issue
    ThirdPartyIntegration,
}

/// Overall security assessment level
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SecurityLevel {
    /// Severe security issues found
    Insecure,
    /// Some security concerns
    Vulnerable,
    /// Minor security issues
    Weak,
    /// Good security posture
    Secure,
    /// Excellent security
    Hardened,
}

/// Input validation security tester
pub struct InputValidationTester {
    config: SecurityTestConfig,
}

impl InputValidationTester {
    /// Create a new input validation tester
    pub fn new(config: SecurityTestConfig) -> Self {
        Self { config }
    }

    /// Test input validation with malicious patterns
    pub fn test_malicious_inputs<F>(&self, testfunction: F) -> CoreResult<SecurityTestResult>
    where
        F: Fn(&[u8]) -> CoreResult<()>,
    {
        let start_time = Instant::now();
        let mut result = SecurityTestResult {
            test_name: "malicious_input_validation".to_string(),
            tests_executed: 0,
            vulnerabilities_found: 0,
            duration: Duration::from_secs(0),
            security_issues: Vec::new(),
            security_level: SecurityLevel::Secure,
        };

        // Test various malicious input patterns
        let patterns = self.generate_malicious_patterns();

        for (i, pattern) in patterns.iter().enumerate() {
            result.tests_executed += 1;

            // Test with timeout
            let test_start = Instant::now();
            let test_result =
                std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| testfunction(pattern)));

            let test_duration = test_start.elapsed();

            match test_result {
                Ok(Ok(())) => {
                    // Function handled input correctly
                }
                Ok(Err(_)) => {
                    // Function returned error - this is expected for malicious input
                }
                Err(_) => {
                    // Function panicked - potential vulnerability
                    result.vulnerabilities_found += 1;
                    result.security_issues.push(SecurityIssue {
                        severity: SecuritySeverity::High,
                        category: SecurityCategory::InputValidation,
                        description: "Function panicked on malicious input".to_string(),
                        trigger_input: format!("{:?}", (i, pattern)),
                        mitigation: Some(
                            "Add proper input validation and error handling".to_string(),
                        ),
                    });
                }
            }

            // Check for potential DoS (excessive execution time)
            if test_duration > self.config.test_timeout {
                result.vulnerabilities_found += 1;
                result.security_issues.push(SecurityIssue {
                    severity: SecuritySeverity::Medium,
                    category: SecurityCategory::DenialOfService,
                    description: format!("{:?}", test_duration),
                    trigger_input: format!("{:?}", (i, pattern)),
                    mitigation: Some("Add input size limits and timeouts".to_string()),
                });
            }
        }

        result.duration = start_time.elapsed();
        result.security_level = self.assess_security_level(&result.security_issues);

        Ok(result)
    }

    /// Test bounds checking with edge cases
    pub fn test_bounds_checking<F>(&self, testfunction: F) -> CoreResult<SecurityTestResult>
    where
        F: Fn(usize, usize) -> CoreResult<()>,
    {
        let start_time = Instant::now();
        let mut result = SecurityTestResult {
            test_name: "bounds_checking".to_string(),
            tests_executed: 0,
            vulnerabilities_found: 0,
            duration: Duration::from_secs(0),
            security_issues: Vec::new(),
            security_level: SecurityLevel::Secure,
        };

        // Test boundary conditions
        let test_cases = vec![
            (0, 0),                   // Zero-zero case
            (0, 1),                   // Zero start
            (1, 0),                   // Zero length
            (usize::MAX, 1),          // Maximum start
            (1, usize::MAX),          // Maximum length
            (usize::MAX, usize::MAX), // Maximum both
            (usize::MAX - 1, 2),      // Overflow potential
        ];

        for (start, length) in test_cases {
            result.tests_executed += 1;

            let test_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
                testfunction(start, length)
            }));

            match test_result {
                Ok(Ok(())) => {
                    // Check if this should have been an error
                    if start.saturating_add(length) < start {
                        // Integer overflow occurred but wasn't caught
                        result.vulnerabilities_found += 1;
                        result.security_issues.push(SecurityIssue {
                            severity: SecuritySeverity::High,
                            category: SecurityCategory::IntegerOverflow,
                            description: "Integer overflow not detected".to_string(),
                            trigger_input: format!("{:?}", (start, length)),
                            mitigation: Some(
                                "Add overflow checks in bounds validation".to_string(),
                            ),
                        });
                    }
                }
                Ok(Err(_)) => {
                    // Expected error for invalid bounds
                }
                Err(_) => {
                    // Panic indicates potential vulnerability
                    result.vulnerabilities_found += 1;
                    result.security_issues.push(SecurityIssue {
                        severity: SecuritySeverity::Critical,
                        category: SecurityCategory::OutOfBounds,
                        description: "Function panicked on bounds check".to_string(),
                        trigger_input: format!("{:?}", (start, length)),
                        mitigation: Some("Implement safe bounds checking".to_string()),
                    });
                }
            }
        }

        result.duration = start_time.elapsed();
        result.security_level = self.assess_security_level(&result.security_issues);

        Ok(result)
    }

    /// Generate malicious input patterns
    #[allow(clippy::vec_init_then_push)]
    fn generate_malicious_patterns(&self) -> Vec<Vec<u8>> {
        let mut patterns = Vec::new();

        // Empty input
        patterns.push(vec![]);

        // Very large input
        patterns.push(vec![0xAA; self.config.max_input_size]);

        // Input with null bytes
        patterns.push(vec![0x00; 100]);

        // Input with high bytes
        patterns.push(vec![0xFF; 100]);

        // Patterns that might trigger buffer overflows
        for size in [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] {
            if size <= self.config.max_input_size {
                patterns.push(vec![0x41; size]); // 'A' pattern
                patterns.push(vec![0x90; size]); // NOP pattern
            }
        }

        // Format string patterns (might be relevant for some functions)
        patterns.push(b"%s%s%s%s%s%s%s%s%s%s".to_vec());
        patterns.push(b"%x%x%x%x%x%x%x%x%x%x".to_vec());
        patterns.push(b"%n%n%n%n%n%n%n%n%n%n".to_vec());

        // SQL injection patterns (might be relevant for database operations)
        patterns.push(b"' OR '1'='1".to_vec());
        patterns.push(b"'; DROP TABLE users; --".to_vec());

        // Path traversal patterns
        patterns.push(b"../../../etc/passwd".to_vec());
        patterns.push(b"..\\..\\..\\windows\\system32\\config\\sam".to_vec());

        // Unicode/encoding issues
        patterns.push(vec![0xC0, 0x80]); // Overlong encoding
        patterns.push(vec![0xED, 0xA0, 0x80]); // Surrogate
        patterns.push(vec![0xFF, 0xFE]); // BOM

        // Limit to requested number of patterns
        patterns.truncate(self.config.malicious_patterns);
        patterns
    }

    /// Assess overall security level based on issues found
    fn assess_security_level(&self, issues: &[SecurityIssue]) -> SecurityLevel {
        let critical_count = issues
            .iter()
            .filter(|i| i.severity == SecuritySeverity::Critical)
            .count();
        let high_count = issues
            .iter()
            .filter(|i| i.severity == SecuritySeverity::High)
            .count();
        let medium_count = issues
            .iter()
            .filter(|i| i.severity == SecuritySeverity::Medium)
            .count();

        if critical_count > 0 {
            SecurityLevel::Insecure
        } else if high_count > 2 {
            SecurityLevel::Vulnerable
        } else if high_count > 0 || medium_count > 5 {
            SecurityLevel::Weak
        } else if medium_count > 0 {
            SecurityLevel::Secure
        } else {
            SecurityLevel::Hardened
        }
    }
}

/// Memory safety security tester
pub struct MemorySafetyTester {
    #[allow(dead_code)]
    config: SecurityTestConfig,
}

impl MemorySafetyTester {
    /// Create a new memory safety tester
    pub fn new(config: SecurityTestConfig) -> Self {
        Self { config }
    }

    /// Test for potential memory leaks
    pub fn test_memory_leaks<F>(&self, testfunction: F) -> CoreResult<SecurityTestResult>
    where
        F: Fn() -> CoreResult<()>,
    {
        let start_time = Instant::now();
        let mut result = SecurityTestResult {
            test_name: "memory_leak_detection".to_string(),
            tests_executed: 0,
            vulnerabilities_found: 0,
            duration: Duration::from_secs(0),
            security_issues: Vec::new(),
            security_level: SecurityLevel::Secure,
        };

        // Get initial memory usage
        let initial_memory = self.get_memory_usage();

        // Run _function multiple times to detect leaks
        for i in 0..100 {
            result.tests_executed += 1;

            match testfunction() {
                Ok(()) => {}
                Err(_) => {
                    // Function errors are not necessarily security issues
                }
            }

            // Check memory usage periodically
            if i % 10 == 0 {
                if let Ok(current_memory) = self.get_memory_usage() {
                    if let Ok(initial) = initial_memory {
                        let memory_growth = current_memory.saturating_sub(initial);

                        // If memory has grown significantly, it might indicate a leak
                        if memory_growth > 10 * 1024 * 1024 {
                            // 10MB threshold
                            result.vulnerabilities_found += 1;
                            result.security_issues.push(SecurityIssue {
                                severity: SecuritySeverity::Medium,
                                category: SecurityCategory::MemorySafety,
                                description: format!(
                                    "Potential memory leak detected: {} MB growth",
                                    memory_growth / (1024 * 1024)
                                ),
                                trigger_input: format!("After {} iterations", i),
                                mitigation: Some(
                                    "Review memory management and cleanup".to_string(),
                                ),
                            });
                            break; // Stop testing once leak is detected
                        }
                    }
                }
            }
        }

        result.duration = start_time.elapsed();
        result.security_level = self.assess_security_level(&result.security_issues);

        Ok(result)
    }

    /// Test for use-after-free vulnerabilities (conceptual, as Rust prevents most of these)
    pub fn test_use_after_free(&self) -> CoreResult<SecurityTestResult> {
        let start_time = Instant::now();
        let result = SecurityTestResult {
            test_name: "use_after_free_detection".to_string(),
            tests_executed: 1,
            vulnerabilities_found: 0,
            duration: start_time.elapsed(),
            security_issues: vec![SecurityIssue {
                severity: SecuritySeverity::Info,
                category: SecurityCategory::MemorySafety,
                description: "Rust's ownership system prevents use-after-free vulnerabilities"
                    .to_string(),
                trigger_input: "N/A".to_string(),
                mitigation: Some("Continue using Rust's safe memory management".to_string()),
            }],
            security_level: SecurityLevel::Hardened,
        };

        Ok(result)
    }

    /// Get current memory usage
    fn get_memory_usage(&self) -> CoreResult<usize> {
        #[cfg(target_os = "linux")]
        {
            use std::fs;
            let status = fs::read_to_string("/proc/self/status").map_err(|e| {
                CoreError::IoError(ErrorContext::new(format!(
                    "Failed to read memory status: {}",
                    e
                )))
            })?;

            for line in status.lines() {
                if line.starts_with("VmRSS:") {
                    let parts: Vec<&str> = line.split_whitespace().collect();
                    if parts.len() >= 2 {
                        let kb: usize = parts[1].parse().map_err(|e| {
                            CoreError::ValidationError(crate::error::ErrorContext::new(format!(
                                "Failed to parse memory: {}",
                                e
                            )))
                        })?;
                        return Ok(kb * 1024);
                    }
                }
            }
        }

        // Fallback for non-Linux systems
        Ok(0)
    }

    /// Assess security level
    fn assess_security_level(&self, issues: &[SecurityIssue]) -> SecurityLevel {
        let critical_count = issues
            .iter()
            .filter(|i| i.severity == SecuritySeverity::Critical)
            .count();
        let high_count = issues
            .iter()
            .filter(|i| i.severity == SecuritySeverity::High)
            .count();
        let medium_count = issues
            .iter()
            .filter(|i| i.severity == SecuritySeverity::Medium)
            .count();

        if critical_count > 0 {
            SecurityLevel::Insecure
        } else if high_count > 0 {
            SecurityLevel::Vulnerable
        } else if medium_count > 2 {
            SecurityLevel::Weak
        } else if medium_count > 0 {
            SecurityLevel::Secure
        } else {
            SecurityLevel::Hardened
        }
    }
}

/// Third-party vulnerability assessment
pub struct VulnerabilityAssessment {
    config: SecurityTestConfig,
}

impl VulnerabilityAssessment {
    /// Create a new vulnerability assessment
    pub fn new(config: SecurityTestConfig) -> Self {
        Self { config }
    }

    /// Perform comprehensive security audit
    pub fn perform_security_audit(&self) -> CoreResult<SecurityAuditReport> {
        let start_time = Instant::now();

        let mut report = SecurityAuditReport {
            audit_timestamp: std::time::SystemTime::now(),
            total_tests: 0,
            passed_tests: 0,
            failed_tests: 0,
            vulnerabilities: Vec::new(),
            recommendations: Vec::new(),
            overall_score: 0.0,
            security_level: SecurityLevel::Secure,
            duration: Duration::from_secs(0),
        };

        // Dependency vulnerability scan
        self.scan_dependencies(&mut report)?;

        // Code security analysis
        self.analyzecode_security(&mut report)?;

        // Configuration security check
        self.check_configuration_security(&mut report)?;

        // Third-party integration security
        self.assess_third_party_security(&mut report)?;

        report.duration = start_time.elapsed();
        report.overall_score = self.calculate_security_score(&report);
        report.security_level = self.determine_security_level(report.overall_score);

        Ok(report)
    }

    /// Scan dependencies for known vulnerabilities
    fn scan_dependencies(&self, report: &mut SecurityAuditReport) -> CoreResult<()> {
        report.total_tests += 1;

        // Check for known vulnerable dependencies
        let vulnerable_deps = self.check_vulnerable_dependencies()?;

        if vulnerable_deps.is_empty() {
            report.passed_tests += 1;
        } else {
            report.failed_tests += 1;
            for dep in vulnerable_deps {
                report.vulnerabilities.push(SecurityVulnerability {
                    id: dep.name.to_string(),
                    severity: SecuritySeverity::High,
                    category: SecurityCategory::DependencyVuln,
                    title: dep.name.to_string(),
                    description: dep.description,
                    affected_component: dep.name.clone(),
                    cve_id: dep.cve_id,
                    mitigation: format!("{}, {}", dep.name, dep.fixed_version),
                });
            }
        }

        Ok(())
    }

    /// Analyze code security patterns
    fn analyzecode_security(&self, report: &mut SecurityAuditReport) -> CoreResult<()> {
        report.total_tests += 1;

        // Static analysis for security patterns
        let security_issues = self.perform_static_analysis()?;

        if security_issues.is_empty() {
            report.passed_tests += 1;
        } else {
            report.failed_tests += 1;
            for issue in security_issues {
                report.vulnerabilities.push(issue);
            }
        }

        Ok(())
    }

    /// Check configuration security
    fn check_configuration_security(&self, report: &mut SecurityAuditReport) -> CoreResult<()> {
        report.total_tests += 1;

        let config_issues = self.audit_configuration()?;

        if config_issues.is_empty() {
            report.passed_tests += 1;
            report
                .recommendations
                .push("Configuration security: PASS".to_string());
        } else {
            report.failed_tests += 1;
            for issue in config_issues {
                report.vulnerabilities.push(issue);
            }
        }

        Ok(())
    }

    /// Assess third-party integration security
    fn assess_third_party_security(&self, report: &mut SecurityAuditReport) -> CoreResult<()> {
        report.total_tests += 1;

        // Check for insecure third-party integrations
        let integration_issues = self.check_third_party_integrations()?;

        if integration_issues.is_empty() {
            report.passed_tests += 1;
            report
                .recommendations
                .push("Third-party integrations: SECURE".to_string());
        } else {
            report.failed_tests += 1;
            for issue in integration_issues {
                report.vulnerabilities.push(issue);
            }
        }

        Ok(())
    }

    /// Check for vulnerable dependencies
    fn check_vulnerable_dependencies(&self) -> CoreResult<Vec<VulnerableDependency>> {
        // In a real implementation, this would check against CVE databases
        // For now, return empty list (no vulnerabilities found)
        Ok(vec![])
    }

    /// Perform static security analysis
    fn perform_static_analysis(&self) -> CoreResult<Vec<SecurityVulnerability>> {
        // Check for common security anti-patterns
        // This is a simplified version - real implementation would use AST analysis

        // Check for potential unsafe blocks (already audited in Rust)
        let vulnerabilities = vec![SecurityVulnerability {
            id: "SAFE-001".to_string(),
            severity: SecuritySeverity::Info,
            category: SecurityCategory::MemorySafety,
            title: "Memory Safety Analysis".to_string(),
            description: "Rust's type system prevents most memory safety vulnerabilities"
                .to_string(),
            affected_component: "core".to_string(),
            cve_id: None,
            mitigation: "Continue using Rust's safe abstractions".to_string(),
        }];

        Ok(vulnerabilities)
    }

    /// Audit configuration security
    fn audit_configuration(&self) -> CoreResult<Vec<SecurityVulnerability>> {
        let issues = Vec::new();

        // Check for insecure default configurations
        // This would check actual config files in a real implementation

        // For now, assume secure configuration
        Ok(issues)
    }

    /// Check third-party integrations
    fn check_third_party_integrations(&self) -> CoreResult<Vec<SecurityVulnerability>> {
        let issues = Vec::new();

        // Check for insecure external API usage
        // Check for unencrypted communications
        // Check for insecure authentication methods

        // For now, assume secure integrations
        Ok(issues)
    }

    /// Calculate overall security score
    fn calculate_security_score(&self, report: &SecurityAuditReport) -> f64 {
        if report.total_tests == 0 {
            return 0.0;
        }

        let base_score = (report.passed_tests as f64 / report.total_tests as f64) * 100.0;

        // Reduce score based on vulnerability severity
        let mut penalty = 0.0;
        for vuln in &report.vulnerabilities {
            match vuln.severity {
                SecuritySeverity::Critical => penalty += 25.0,
                SecuritySeverity::High => penalty += 15.0,
                SecuritySeverity::Medium => penalty += 8.0,
                SecuritySeverity::Low => penalty += 3.0,
                SecuritySeverity::Info => penalty += 0.0,
            }
        }

        (base_score - penalty).max(0.0)
    }

    /// Determine security level from score
    fn determine_security_level(&self, score: f64) -> SecurityLevel {
        match score {
            s if s >= 95.0 => SecurityLevel::Hardened,
            s if s >= 85.0 => SecurityLevel::Secure,
            s if s >= 70.0 => SecurityLevel::Weak,
            s if s >= 50.0 => SecurityLevel::Vulnerable,
            _ => SecurityLevel::Insecure,
        }
    }
}

/// Security audit report
#[derive(Debug, Clone)]
pub struct SecurityAuditReport {
    /// Audit timestamp
    pub audit_timestamp: std::time::SystemTime,
    /// Total number of tests performed
    pub total_tests: usize,
    /// Number of tests passed
    pub passed_tests: usize,
    /// Number of tests failed
    pub failed_tests: usize,
    /// Vulnerabilities found
    pub vulnerabilities: Vec<SecurityVulnerability>,
    /// Security recommendations
    pub recommendations: Vec<String>,
    /// Overall security score (0-100)
    pub overall_score: f64,
    /// Security level assessment
    pub security_level: SecurityLevel,
    /// Total audit duration
    pub duration: Duration,
}

/// Security vulnerability details
#[derive(Debug, Clone)]
pub struct SecurityVulnerability {
    /// Unique vulnerability identifier
    pub id: String,
    /// Severity level
    pub severity: SecuritySeverity,
    /// Vulnerability category
    pub category: SecurityCategory,
    /// Vulnerability title
    pub title: String,
    /// Detailed description
    pub description: String,
    /// Affected component
    pub affected_component: String,
    /// CVE identifier if applicable
    pub cve_id: Option<String>,
    /// Mitigation strategy
    pub mitigation: String,
}

/// Vulnerable dependency information
#[derive(Debug, Clone)]
pub struct VulnerableDependency {
    /// Dependency name
    pub name: String,
    /// Current version
    pub current_version: String,
    /// Fixed version
    pub fixed_version: String,
    /// Vulnerability description
    pub description: String,
    /// CVE identifier
    pub cve_id: Option<String>,
}

/// High-level security testing utilities
pub struct SecurityTestUtils;

impl SecurityTestUtils {
    /// Create a comprehensive security test suite
    pub fn create_security_test_suite(name: &str, config: TestConfig) -> crate::testing::TestSuite {
        let mut suite = crate::testing::TestSuite::new(name, config);
        let security_config = SecurityTestConfig::default()
            .with_malicious_patterns(100)
            .with_max_input_size(1024);

        // Input validation tests
        let security_config_1 = security_config.clone();
        suite.add_test("malicious_input_validation", move |_runner| {
            let tester = InputValidationTester::new(security_config_1.clone());

            let result = tester.test_malicious_inputs(|input| {
                // Test a simple validation function
                if input.len() > 1000 {
                    Err(CoreError::ValidationError(crate::error::ErrorContext::new(
                        "Input too large",
                    )))
                } else if input.is_empty() {
                    Err(CoreError::ValidationError(crate::error::ErrorContext::new(
                        "Input cannot be empty",
                    )))
                } else {
                    Ok(())
                }
            })?;

            // Check if any critical vulnerabilities were found
            if result.security_level == SecurityLevel::Insecure {
                return Ok(TestResult::failure(
                    result.duration,
                    result.tests_executed,
                    format!(
                        "Critical security vulnerabilities found: {}",
                        result.vulnerabilities_found
                    ),
                ));
            }

            Ok(TestResult::success(result.duration, result.tests_executed))
        });

        // Bounds checking tests
        let security_config_2 = security_config.clone();
        suite.add_test("bounds_checking", move |_runner| {
            let tester = InputValidationTester::new(security_config_2.clone());

            let result = tester.test_bounds_checking(|start, length| {
                // Test bounds checking function
                let end = start.checked_add(length).ok_or_else(|| {
                    CoreError::ValidationError(crate::error::ErrorContext::new(
                        "Integer overflow in bounds calculation",
                    ))
                })?;

                if end > 1000 {
                    Err(CoreError::ValidationError(crate::error::ErrorContext::new(
                        "Bounds exceed maximum allowed",
                    )))
                } else {
                    Ok(())
                }
            })?;

            if result.security_level == SecurityLevel::Insecure
                || result.security_level == SecurityLevel::Vulnerable
            {
                return Ok(TestResult::failure(
                    result.duration,
                    result.tests_executed,
                    format!(
                        "Bounds checking vulnerabilities found: {}",
                        result.vulnerabilities_found
                    ),
                ));
            }

            Ok(TestResult::success(result.duration, result.tests_executed))
        });

        // Memory safety tests
        let security_config_3 = security_config.clone();
        suite.add_test("memory_safety", move |_runner| {
            let tester = MemorySafetyTester::new(security_config_3.clone());

            let result = tester.test_memory_leaks(|| {
                // Test function that should not leak memory
                let data = vec![0u8; 1000];
                Ok(())
            })?;

            if result.vulnerabilities_found > 0 {
                return Ok(TestResult::failure(
                    result.duration,
                    result.tests_executed,
                    format!(
                        "Memory safety issues found: {}",
                        result.vulnerabilities_found
                    ),
                ));
            }

            Ok(TestResult::success(result.duration, result.tests_executed))
        });

        // Use-after-free test (informational for Rust)
        let security_config_clone2 = security_config.clone();
        suite.add_test("use_after_free", move |_runner| {
            let tester = MemorySafetyTester::new(security_config_clone2.clone());
            let result = tester.test_use_after_free()?;

            // This should always pass in Rust
            Ok(TestResult::success(result.duration, result.tests_executed))
        });

        // Third-party vulnerability assessment
        let security_config_clone3 = security_config.clone();
        suite.add_test("vulnerability_assessment", move |_runner| {
            let assessment = VulnerabilityAssessment::new(security_config_clone3.clone());
            let report = assessment.perform_security_audit()?;

            if report.security_level == SecurityLevel::Insecure
                || report.security_level == SecurityLevel::Vulnerable
            {
                return Ok(TestResult::failure(
                    report.duration,
                    report.total_tests,
                    format!(
                        "Security audit failed: {} vulnerabilities found, score: {:.1}",
                        report.vulnerabilities.len(),
                        report.overall_score
                    ),
                ));
            }

            Ok(TestResult::success(report.duration, report.total_tests))
        });

        suite
    }
}

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

    #[test]
    fn test_security_config() {
        let config = SecurityTestConfig::new()
            .with_max_input_size(2048)
            .with_malicious_patterns(500)
            .with_bounds_checking(true)
            .with_memory_safety(false);

        assert_eq!(config.max_input_size, 2048);
        assert_eq!(config.malicious_patterns, 500);
        assert!(config.test_bounds_checking);
        assert!(!config.test_memory_safety);
    }

    #[test]
    fn test_security_severity() {
        assert_eq!(SecuritySeverity::Critical, SecuritySeverity::Critical);
        assert_ne!(SecuritySeverity::Critical, SecuritySeverity::High);
    }

    #[test]
    fn test_security_level_assessment() {
        let tester = InputValidationTester::new(SecurityTestConfig::default());

        // Test with no issues
        let level = tester.assess_security_level(&[]);
        assert_eq!(level, SecurityLevel::Hardened);

        // Test with critical issue
        let critical_issue = SecurityIssue {
            severity: SecuritySeverity::Critical,
            category: SecurityCategory::BufferOverflow,
            description: "Test issue".to_string(),
            trigger_input: "test".to_string(),
            mitigation: None,
        };
        let level = tester.assess_security_level(&[critical_issue]);
        assert_eq!(level, SecurityLevel::Insecure);
    }

    #[test]
    fn test_malicious_pattern_generation() {
        let tester =
            InputValidationTester::new(SecurityTestConfig::default().with_malicious_patterns(10));
        let patterns = tester.generate_malicious_patterns();

        assert_eq!(patterns.len(), 10);
        assert!(patterns.iter().any(|p| p.is_empty())); // Should include empty pattern
    }

    #[test]
    fn test_vulnerability_assessment() {
        let assessment = VulnerabilityAssessment::new(SecurityTestConfig::default());
        let report = assessment
            .perform_security_audit()
            .expect("Operation failed");

        assert!(report.total_tests > 0);
        assert!(report.passed_tests > 0);
        assert!(report.overall_score >= 0.0);
        assert!(report.overall_score <= 100.0);
    }

    #[test]
    fn test_security_score_calculation() {
        let assessment = VulnerabilityAssessment::new(SecurityTestConfig::default());

        // Test with no vulnerabilities
        let report = SecurityAuditReport {
            audit_timestamp: std::time::SystemTime::now(),
            total_tests: 10,
            passed_tests: 10,
            failed_tests: 0,
            vulnerabilities: vec![],
            recommendations: vec![],
            overall_score: 0.0,
            security_level: SecurityLevel::Secure,
            duration: Duration::from_secs(1),
        };

        let score = assessment.calculate_security_score(&report);
        assert_eq!(score, 100.0);

        // Test with critical vulnerability
        let report_with_critical = SecurityAuditReport {
            audit_timestamp: std::time::SystemTime::now(),
            total_tests: 10,
            passed_tests: 9,
            failed_tests: 1,
            vulnerabilities: vec![SecurityVulnerability {
                id: "TEST-001".to_string(),
                severity: SecuritySeverity::Critical,
                category: SecurityCategory::MemorySafety,
                title: "Test vulnerability".to_string(),
                description: "Test description".to_string(),
                affected_component: "test".to_string(),
                cve_id: None,
                mitigation: "Test mitigation".to_string(),
            }],
            recommendations: vec![],
            overall_score: 0.0,
            security_level: SecurityLevel::Secure,
            duration: Duration::from_secs(1),
        };

        let score_with_critical = assessment.calculate_security_score(&report_with_critical);
        assert!(score_with_critical < 100.0);
        assert!(score_with_critical >= 0.0);
    }

    #[test]
    fn test_security_level_determination() {
        let assessment = VulnerabilityAssessment::new(SecurityTestConfig::default());

        assert_eq!(
            assessment.determine_security_level(100.0),
            SecurityLevel::Hardened
        );
        assert_eq!(
            assessment.determine_security_level(90.0),
            SecurityLevel::Secure
        );
        assert_eq!(
            assessment.determine_security_level(75.0),
            SecurityLevel::Weak
        );
        assert_eq!(
            assessment.determine_security_level(60.0),
            SecurityLevel::Vulnerable
        );
        assert_eq!(
            assessment.determine_security_level(30.0),
            SecurityLevel::Insecure
        );
    }
}
