#![cfg_attr(coverage_nightly, coverage(off))]
//! Enhanced reporting tests part 1 - Basic tests, health score tests
//! Extracted for file health compliance (CB-040)

use super::*;
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;

// =============================================================================
// Test Fixtures
// =============================================================================

/// Create a minimal AnalysisResults for testing
pub fn create_minimal_analysis_results() -> AnalysisResults {
    AnalysisResults {
        total_duration: Duration::from_secs(5),
        analyzed_files: 10,
        total_lines: 1000,
        complexity_analysis: None,
        dead_code_analysis: None,
        duplication_analysis: None,
        tdg_analysis: None,
        big_o_analysis: None,
    }
}

/// Create AnalysisResults with all analysis types populated
pub fn create_full_analysis_results() -> AnalysisResults {
    AnalysisResults {
        total_duration: Duration::from_secs(60),
        analyzed_files: 100,
        total_lines: 50000,
        complexity_analysis: Some(ComplexityAnalysis {
            total_cyclomatic: 800,
            total_cognitive: 1200,
            functions: 80,
            max_cyclomatic: 25,
            high_complexity_functions: 12,
            distribution: vec![20, 30, 15, 10, 5],
        }),
        dead_code_analysis: Some(DeadCodeAnalysis {
            dead_lines: 500,
            dead_functions: 15,
            dead_code_percentage: 1.0,
        }),
        duplication_analysis: Some(DuplicationAnalysis {
            duplicated_lines: 800,
            duplicate_blocks: 25,
            duplication_percentage: 1.6,
        }),
        tdg_analysis: Some(TdgAnalysis {
            average_tdg: 3.5,
            max_tdg: 6.0,
            high_tdg_files: 8,
        }),
        big_o_analysis: Some(BigOAnalysis {
            analyzed_functions: 80,
            high_complexity_count: 5,
            complexity_distribution: {
                let mut map = HashMap::new();
                map.insert("O(1)".to_string(), 30);
                map.insert("O(n)".to_string(), 35);
                map.insert("O(n^2)".to_string(), 10);
                map.insert("O(log n)".to_string(), 5);
                map
            },
        }),
    }
}

/// Create a healthy analysis result with good scores
pub fn create_healthy_analysis_results() -> AnalysisResults {
    AnalysisResults {
        total_duration: Duration::from_secs(30),
        analyzed_files: 50,
        total_lines: 20000,
        complexity_analysis: Some(ComplexityAnalysis {
            total_cyclomatic: 300,
            total_cognitive: 400,
            functions: 60,
            max_cyclomatic: 10,
            high_complexity_functions: 0,
            distribution: vec![40, 15, 5, 0, 0],
        }),
        dead_code_analysis: Some(DeadCodeAnalysis {
            dead_lines: 50,
            dead_functions: 2,
            dead_code_percentage: 0.25,
        }),
        duplication_analysis: Some(DuplicationAnalysis {
            duplicated_lines: 100,
            duplicate_blocks: 5,
            duplication_percentage: 0.5,
        }),
        tdg_analysis: Some(TdgAnalysis {
            average_tdg: 2.0,
            max_tdg: 3.0,
            high_tdg_files: 2,
        }),
        big_o_analysis: None,
    }
}

/// Create an unhealthy analysis result with poor scores
pub fn create_unhealthy_analysis_results() -> AnalysisResults {
    AnalysisResults {
        total_duration: Duration::from_secs(120),
        analyzed_files: 200,
        total_lines: 100000,
        complexity_analysis: Some(ComplexityAnalysis {
            total_cyclomatic: 6000,
            total_cognitive: 8000,
            functions: 100,
            max_cyclomatic: 80,
            high_complexity_functions: 40,
            distribution: vec![5, 10, 20, 25, 40],
        }),
        dead_code_analysis: Some(DeadCodeAnalysis {
            dead_lines: 20000,
            dead_functions: 100,
            dead_code_percentage: 20.0,
        }),
        duplication_analysis: Some(DuplicationAnalysis {
            duplicated_lines: 25000,
            duplicate_blocks: 150,
            duplication_percentage: 25.0,
        }),
        tdg_analysis: Some(TdgAnalysis {
            average_tdg: 7.0,
            max_tdg: 12.0,
            high_tdg_files: 50,
        }),
        big_o_analysis: Some(BigOAnalysis {
            analyzed_functions: 100,
            high_complexity_count: 30,
            complexity_distribution: {
                let mut map = HashMap::new();
                map.insert("O(n^3)".to_string(), 20);
                map.insert("O(n^2)".to_string(), 40);
                map.insert("O(n)".to_string(), 30);
                map.insert("O(1)".to_string(), 10);
                map
            },
        }),
    }
}

/// Create a ReportConfig for testing
pub fn create_test_report_config() -> ReportConfig {
    ReportConfig {
        project_path: PathBuf::from("/test/project"),
        output_format: ReportFormat::Markdown,
        include_visualizations: true,
        include_executive_summary: true,
        include_recommendations: true,
        confidence_threshold: 80,
        output_path: None,
    }
}

// =============================================================================
// Basic Tests
// =============================================================================

#[test]
fn test_health_score_calculation() {
    let service = EnhancedReportingService::default();

    let results = AnalysisResults {
        total_duration: std::time::Duration::from_secs(10),
        analyzed_files: 100,
        total_lines: 10000,
        complexity_analysis: Some(ComplexityAnalysis {
            total_cyclomatic: 500,
            total_cognitive: 800,
            functions: 50,
            max_cyclomatic: 15,
            high_complexity_functions: 5,
            distribution: vec![10, 20, 15, 3, 2],
        }),
        dead_code_analysis: Some(DeadCodeAnalysis {
            dead_lines: 100,
            dead_functions: 5,
            dead_code_percentage: 1.0,
        }),
        duplication_analysis: None,
        tdg_analysis: None,
        big_o_analysis: None,
    };

    let score = service.calculate_health_score(&results);
    assert!(score > 80.0);
    assert!(score <= 100.0);
}

#[test]
fn test_risk_assessment() {
    let service = EnhancedReportingService::default();

    let results = AnalysisResults {
        total_duration: std::time::Duration::from_secs(10),
        analyzed_files: 100,
        total_lines: 10000,
        complexity_analysis: Some(ComplexityAnalysis {
            total_cyclomatic: 2000,
            total_cognitive: 3000,
            functions: 50,
            max_cyclomatic: 50,
            high_complexity_functions: 20,
            distribution: vec![5, 10, 10, 10, 15],
        }),
        dead_code_analysis: Some(DeadCodeAnalysis {
            dead_lines: 2000,
            dead_functions: 50,
            dead_code_percentage: 20.0,
        }),
        duplication_analysis: Some(DuplicationAnalysis {
            duplicated_lines: 1500,
            duplicate_blocks: 30,
            duplication_percentage: 15.0,
        }),
        tdg_analysis: Some(TdgAnalysis {
            average_tdg: 5.0,
            max_tdg: 8.0,
            high_tdg_files: 20,
        }),
        big_o_analysis: None,
    };

    let risk = service.assess_overall_risk(&results);
    assert!(matches!(risk, RiskLevel::High | RiskLevel::Critical));
}

// =============================================================================
// EnhancedReportingService Creation Tests
// =============================================================================

#[test]
fn test_service_creation() {
    let service = EnhancedReportingService::new();
    assert!(service.is_ok());
}

#[test]
fn test_service_default() {
    let service = EnhancedReportingService::default();
    assert!(true, "Service created via Default trait");
    drop(service);
}

// =============================================================================
// Health Score Calculation Tests
// =============================================================================

#[test]
fn test_health_score_minimal_results() {
    let service = EnhancedReportingService::default();
    let results = create_minimal_analysis_results();
    let score = service.calculate_health_score(&results);
    assert_eq!(score, 100.0);
}

#[test]
fn test_health_score_healthy_results() {
    let service = EnhancedReportingService::default();
    let results = create_healthy_analysis_results();
    let score = service.calculate_health_score(&results);
    assert!(score >= 80.0, "Expected score >= 80.0, got {}", score);
    assert!(score <= 100.0, "Expected score <= 100.0, got {}", score);
}

#[test]
fn test_health_score_unhealthy_results() {
    let service = EnhancedReportingService::default();
    let results = create_unhealthy_analysis_results();
    let score = service.calculate_health_score(&results);
    assert!(score < 50.0, "Expected score < 50.0, got {}", score);
    assert!(score >= 0.0, "Score should never be negative");
}

#[test]
fn test_health_score_only_complexity() {
    let service = EnhancedReportingService::default();
    let results = AnalysisResults {
        total_duration: Duration::from_secs(10),
        analyzed_files: 50,
        total_lines: 10000,
        complexity_analysis: Some(ComplexityAnalysis {
            total_cyclomatic: 1500,
            total_cognitive: 2000,
            functions: 50,
            max_cyclomatic: 35,
            high_complexity_functions: 15,
            distribution: vec![10, 15, 10, 10, 5],
        }),
        dead_code_analysis: None,
        duplication_analysis: None,
        tdg_analysis: None,
        big_o_analysis: None,
    };
    let score = service.calculate_health_score(&results);
    assert!(score <= 80.0, "Expected score <= 80.0, got {}", score);
    assert!(score >= 60.0, "Expected score >= 60.0, got {}", score);
}

#[test]
fn test_health_score_only_dead_code() {
    let service = EnhancedReportingService::default();
    let results = AnalysisResults {
        total_duration: Duration::from_secs(10),
        analyzed_files: 50,
        total_lines: 10000,
        complexity_analysis: None,
        dead_code_analysis: Some(DeadCodeAnalysis {
            dead_lines: 1500,
            dead_functions: 30,
            dead_code_percentage: 15.0,
        }),
        duplication_analysis: None,
        tdg_analysis: None,
        big_o_analysis: None,
    };
    let score = service.calculate_health_score(&results);
    assert!(score <= 85.0, "Expected score <= 85.0, got {}", score);
}

#[test]
fn test_health_score_only_duplication() {
    let service = EnhancedReportingService::default();
    let results = AnalysisResults {
        total_duration: Duration::from_secs(10),
        analyzed_files: 50,
        total_lines: 10000,
        complexity_analysis: None,
        dead_code_analysis: None,
        duplication_analysis: Some(DuplicationAnalysis {
            duplicated_lines: 2000,
            duplicate_blocks: 40,
            duplication_percentage: 20.0,
        }),
        tdg_analysis: None,
        big_o_analysis: None,
    };
    let score = service.calculate_health_score(&results);
    assert!(score <= 85.0, "Expected score <= 85.0, got {}", score);
}

#[test]
fn test_health_score_only_tdg() {
    let service = EnhancedReportingService::default();
    let results = AnalysisResults {
        total_duration: Duration::from_secs(10),
        analyzed_files: 50,
        total_lines: 10000,
        complexity_analysis: None,
        dead_code_analysis: None,
        duplication_analysis: None,
        tdg_analysis: Some(TdgAnalysis {
            average_tdg: 7.0,
            max_tdg: 12.0,
            high_tdg_files: 15,
        }),
        big_o_analysis: None,
    };
    let score = service.calculate_health_score(&results);
    assert!(score <= 80.0, "Expected score <= 80.0, got {}", score);
}

#[test]
fn test_health_score_never_negative() {
    let service = EnhancedReportingService::default();
    let results = AnalysisResults {
        total_duration: Duration::from_secs(1000),
        analyzed_files: 1000,
        total_lines: 1000,
        complexity_analysis: Some(ComplexityAnalysis {
            total_cyclomatic: 100000,
            total_cognitive: 200000,
            functions: 100,
            max_cyclomatic: 500,
            high_complexity_functions: 80,
            distribution: vec![0, 0, 0, 0, 100],
        }),
        dead_code_analysis: Some(DeadCodeAnalysis {
            dead_lines: 500,
            dead_functions: 50,
            dead_code_percentage: 50.0,
        }),
        duplication_analysis: Some(DuplicationAnalysis {
            duplicated_lines: 800,
            duplicate_blocks: 80,
            duplication_percentage: 80.0,
        }),
        tdg_analysis: Some(TdgAnalysis {
            average_tdg: 20.0,
            max_tdg: 50.0,
            high_tdg_files: 100,
        }),
        big_o_analysis: None,
    };
    let score = service.calculate_health_score(&results);
    assert!(
        score >= 0.0,
        "Score should never be negative, got {}",
        score
    );
}
