//! Comprehensive Testing Framework for APT-OSTree
//! 
//! This module provides systematic testing for all components and integration points
//! to validate the implementation and discover edge cases.

pub mod unit_tests;
pub mod integration_tests;

use std::path::PathBuf;
use tracing::info;
use serde::{Serialize, Deserialize};

/// Test types
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TestType {
    Unit,
    Integration,
    EndToEnd,
    Performance,
    Security,
    ErrorHandling,
}

/// Test suite runner
pub struct TestSuite {
    config: apt_ostree::TestConfig,
    results: Vec<apt_ostree::TestResult>,
}

impl TestSuite {
    /// Create a new test suite
    pub fn new(config: apt_ostree::TestConfig) -> Self {
        Self {
            config,
            results: Vec::new(),
        }
    }

    /// Run all tests
    pub async fn run_all_tests(&mut self) -> Result<TestSummary, Box<dyn std::error::Error>> {
        info!("🚀 Starting comprehensive APT-OSTree testing suite");
        
        // Create test directories
        self.setup_test_environment().await?;
        
        // Run test categories
        let summary = TestSummary::new();
        
        // Unit tests
        info!("📋 Running unit tests...");
        let unit_results = self.run_unit_tests().await;
        self.results.extend(unit_results);
        
        // Integration tests
        info!("🔗 Running integration tests...");
        let integration_results = self.run_integration_tests().await;
        self.results.extend(integration_results);
        
        // Performance tests (if enabled)
        if self.config.enable_performance_tests {
            info!("⚡ Running performance tests...");
            let performance_results = self.run_performance_tests().await;
            self.results.extend(performance_results);
        }
        
        // Security tests
        info!("🔒 Running security tests...");
        let security_results = self.run_security_tests().await;
        self.results.extend(security_results);
        
        // Error handling tests
        info!("⚠️  Running error handling tests...");
        let error_results = self.run_error_handling_tests().await;
        self.results.extend(error_results);
        
        info!("✅ Testing suite completed");
        Ok(summary)
    }

    /// Run unit tests
    async fn run_unit_tests(&self) -> Vec<apt_ostree::TestResult> {
        let mut results = Vec::new();
        
        // APT integration tests
        results.push(unit_tests::test_apt_integration(&self.config).await);
        
        // OSTree integration tests
        results.push(unit_tests::test_ostree_integration(&self.config).await);
        
        // Package manager tests
        results.push(unit_tests::test_package_manager(&self.config).await);
        
        // Filesystem assembly tests
        results.push(unit_tests::test_filesystem_assembly(&self.config).await);
        
        // Dependency resolution tests
        results.push(unit_tests::test_dependency_resolution(&self.config).await);
        
        // Transaction management tests
        results.push(unit_tests::test_transaction_management(&self.config).await);
        
        // Security authorization tests
        results.push(unit_tests::test_security_authorization(&self.config).await);
        
        // Error handling tests
        results.push(unit_tests::test_error_handling(&self.config).await);
        
        // Logging and metrics tests
        results.push(unit_tests::test_logging_and_metrics(&self.config).await);
        
        // Performance benchmark tests
        results.push(unit_tests::test_performance_benchmarks(&self.config).await);
        
        // Security vulnerability tests
        results.push(unit_tests::test_security_vulnerabilities(&self.config).await);
        
        results
    }

    /// Run integration tests
    async fn run_integration_tests(&self) -> Vec<apt_ostree::TestResult> {
        let mut results = Vec::new();
        
        // Package installation workflow tests
        results.push(integration_tests::test_package_installation_workflow(&self.config).await);
        
        // System upgrade workflow tests
        results.push(integration_tests::test_system_upgrade_workflow(&self.config).await);
        
        // Deployment management workflow tests
        results.push(integration_tests::test_deployment_management_workflow(&self.config).await);
        
        // Transaction lifecycle workflow tests
        results.push(integration_tests::test_transaction_lifecycle_workflow(&self.config).await);
        
        // Error recovery workflow tests
        results.push(integration_tests::test_error_recovery_workflow(&self.config).await);
        
        results
    }

    /// Run performance tests
    async fn run_performance_tests(&self) -> Vec<apt_ostree::TestResult> {
        let mut results = Vec::new();
        
        // Package operation performance tests
        results.push(unit_tests::test_performance_benchmarks(&self.config).await);
        
        // OSTree operation performance tests
        results.push(unit_tests::test_performance_benchmarks(&self.config).await);
        
        results
    }

    /// Run security tests
    async fn run_security_tests(&self) -> Vec<apt_ostree::TestResult> {
        let mut results = Vec::new();
        
        // Security authorization tests
        results.push(unit_tests::test_security_authorization(&self.config).await);
        
        // Security vulnerability tests
        results.push(unit_tests::test_security_vulnerabilities(&self.config).await);
        
        results
    }

    /// Run error handling tests
    async fn run_error_handling_tests(&self) -> Vec<apt_ostree::TestResult> {
        let mut results = Vec::new();
        
        // Error handling tests
        results.push(unit_tests::test_error_handling(&self.config).await);
        
        results
    }

    /// Setup test environment
    async fn setup_test_environment(&self) -> Result<(), Box<dyn std::error::Error>> {
        info!("🔧 Setting up test environment...");
        
        // Create test directories
        std::fs::create_dir_all(&self.config.test_data_dir)?;
        std::fs::create_dir_all(&self.config.temp_dir)?;
        std::fs::create_dir_all(&self.config.ostree_repo_path)?;
        
        info!("✅ Test environment setup completed");
        Ok(())
    }

    /// Get test results
    pub fn get_results(&self) -> &[apt_ostree::TestResult] {
        &self.results
    }

    /// Get test summary
    pub fn get_summary(&self) -> TestSummary {
        let total_tests = self.results.len();
        let passed_tests = self.results.iter().filter(|r| r.success).count();
        let failed_tests = total_tests - passed_tests;
        
        TestSummary {
            total_tests,
            passed_tests,
            failed_tests,
            success_rate: if total_tests > 0 {
                (passed_tests as f64 / total_tests as f64) * 100.0
            } else {
                0.0
            },
        }
    }
}

/// Test summary statistics
#[derive(Debug, Clone)]
pub struct TestSummary {
    pub total_tests: usize,
    pub passed_tests: usize,
    pub failed_tests: usize,
    pub success_rate: f64,
}

impl TestSummary {
    /// Create a new test summary
    pub fn new() -> Self {
        Self {
            total_tests: 0,
            passed_tests: 0,
            failed_tests: 0,
            success_rate: 0.0,
        }
    }

    /// Print test summary
    pub fn print_summary(&self) {
        println!("📊 Test Summary");
        println!("===============");
        println!("Total tests: {}", self.total_tests);
        println!("Passed: {}", self.passed_tests);
        println!("Failed: {}", self.failed_tests);
        println!("Success rate: {:.1}%", self.success_rate);
        
        if self.failed_tests > 0 {
            println!("❌ Some tests failed");
        } else {
            println!("✅ All tests passed");
        }
    }
}

/// Run a simple test suite
pub async fn run_simple_test_suite() -> Result<TestSummary, Box<dyn std::error::Error>> {
    let config = apt_ostree::TestConfig::new();
    let mut test_suite = TestSuite::new(config);
    
    test_suite.run_all_tests().await?;
    
    let summary = test_suite.get_summary();
    summary.print_summary();
    
    Ok(summary)
}

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

    #[tokio::test]
    async fn test_test_suite_creation() {
        let config = apt_ostree::TestConfig::new();
        let test_suite = TestSuite::new(config);
        assert_eq!(test_suite.get_results().len(), 0);
    }

    #[tokio::test]
    async fn test_test_summary_creation() {
        let summary = TestSummary::new();
        assert_eq!(summary.total_tests, 0);
        assert_eq!(summary.passed_tests, 0);
        assert_eq!(summary.failed_tests, 0);
        assert_eq!(summary.success_rate, 0.0);
    }
} 