//! Chicago TDD tests for false positive detection
//!
//! Tests verify the critical bug: ggen.toml is broken but tests pass.
//! This module validates detection of execution-only tests.

use ggen_test_audit::{AssertionStrength, FalsePositiveDetector, TestId};
use std::fs;
use tempfile::TempDir;

/// Test: Detect execution-only tests (is_ok, is_some)
#[test]
fn test_detect_execution_only_tests() {
    // Arrange: Create detector and weak assertions
    let temp_dir = TempDir::new().expect("Failed to create temp dir");
    let detector = FalsePositiveDetector::new(vec![]);

    let weak_assertion = ggen_test_audit::TestAssertion {
        test_id: TestId::new("test_weak").expect("Valid TestId"),
        file_path: temp_dir.path().join("test.rs"),
        assertion_strength: AssertionStrength::Weak,
        assertion_count: 1,
    };

    let strong_assertion = ggen_test_audit::TestAssertion {
        test_id: TestId::new("test_strong").expect("Valid TestId"),
        file_path: temp_dir.path().join("test.rs"),
        assertion_strength: AssertionStrength::Strong,
        assertion_count: 1,
    };

    let assertions = vec![weak_assertion, strong_assertion];

    // Act: Detect execution-only tests
    let false_positives = detector.detect_execution_only_tests(&assertions);

    // Assert: Verify state - should find 1 weak test
    assert_eq!(
        false_positives.len(),
        1,
        "Should detect 1 execution-only test"
    );
    assert_eq!(
        false_positives[0].test_id.as_str(),
        "test_weak",
        "Should identify weak test"
    );
}

/// Test: Detect ggen.toml tests that don't validate parsed values
#[test]
fn test_analyze_ggen_toml_tests_with_weak_assertions() {
    // Arrange: Create test file simulating ggen.toml false positive
    let temp_dir = TempDir::new().expect("Failed to create temp dir");
    let test_file = temp_dir.path().join("config_test.rs");

    // This is the CRITICAL BUG: ggen.toml is broken but test passes
    fs::write(
        &test_file,
        r#"
        #[test]
        fn test_ggen_toml_parsing() {
            let result = parse_ggen_toml("broken.toml");
            assert!(result.is_ok()); // FALSE POSITIVE - doesn't validate values!
        }
        "#,
    )
    .expect("Failed to write test file");

    let detector = FalsePositiveDetector::new(vec![temp_dir.path().to_path_buf()]);

    // Act: Analyze ggen.toml tests
    let false_positives = detector
        .analyze_ggen_toml_tests()
        .expect("Failed to analyze ggen.toml tests");

    // Assert: Verify state - should detect ggen.toml false positive
    assert!(
        !false_positives.is_empty(),
        "Should detect ggen.toml false positive"
    );

    // Verify severity is CRITICAL (this blocks Feature 004)
    assert_eq!(
        false_positives[0].severity,
        ggen_test_audit::Severity::Critical,
        "ggen.toml false positives should be CRITICAL severity"
    );
}

/// Test: ggen.toml test with proper validation is NOT flagged
#[test]
fn test_analyze_ggen_toml_tests_with_strong_assertions() {
    // Arrange: Create test file with proper value validation
    let temp_dir = TempDir::new().expect("Failed to create temp dir");
    let test_file = temp_dir.path().join("config_test_good.rs");

    // This is CORRECT: validates actual parsed values
    fs::write(
        &test_file,
        r#"
        #[test]
        fn test_ggen_toml_parsing() {
            let config = parse_ggen_toml("test.toml").unwrap();
            assert_eq!(config.name, "expected_name"); // STRONG - validates value
            assert_eq!(config.version, "1.0.0"); // STRONG - validates value
        }
        "#,
    )
    .expect("Failed to write test file");

    let detector = FalsePositiveDetector::new(vec![temp_dir.path().to_path_buf()]);

    // Act: Analyze ggen.toml tests
    let false_positives = detector
        .analyze_ggen_toml_tests()
        .expect("Failed to analyze ggen.toml tests");

    // Assert: Verify state - should NOT flag strong assertions
    assert!(
        false_positives.is_empty(),
        "Strongly asserted configs should not be flagged"
    );
}

/// Test: Identify critical path coverage gaps
#[test]
fn test_identify_critical_path_gaps() {
    // Arrange: Create detector and weak assertions for critical paths
    let temp_dir = TempDir::new().expect("Failed to create temp dir");
    let detector = FalsePositiveDetector::new(vec![]);

    let weak_rdf_test = ggen_test_audit::TestAssertion {
        test_id: TestId::new("test_rdf_parser").expect("Valid TestId"),
        file_path: temp_dir.path().join("rdf_test.rs"),
        assertion_strength: AssertionStrength::Weak, // Critical path with weak assertion!
        assertion_count: 1,
    };

    let assertions = vec![weak_rdf_test];

    // Act: Identify critical path gaps
    let gaps = detector.identify_critical_path_gaps(&assertions);

    // Assert: Verify state - should find gaps in critical paths
    assert!(
        !gaps.is_empty(),
        "Should identify critical path coverage gaps"
    );
}

/// Test: Generate comprehensive false positive report
#[test]
fn test_generate_comprehensive_report() {
    // Arrange: Create detector and mixed assertions
    let temp_dir = TempDir::new().expect("Failed to create temp dir");
    let detector = FalsePositiveDetector::new(vec![]);

    let assertions = vec![
        ggen_test_audit::TestAssertion {
            test_id: TestId::new("test1").expect("Valid TestId"),
            file_path: temp_dir.path().join("test.rs"),
            assertion_strength: AssertionStrength::Weak,
            assertion_count: 1,
        },
        ggen_test_audit::TestAssertion {
            test_id: TestId::new("test2").expect("Valid TestId"),
            file_path: temp_dir.path().join("test.rs"),
            assertion_strength: AssertionStrength::Strong,
            assertion_count: 1,
        },
    ];

    // Act: Generate report
    let report = detector
        .generate_report(&assertions)
        .expect("Failed to generate report");

    // Assert: Verify report structure and state
    assert_eq!(report.total_tests_analyzed, 2, "Should analyze 2 tests");
    assert!(
        !report.execution_only_tests.is_empty(),
        "Should detect execution-only tests"
    );
}

/// Test: Empty test suite returns valid report
#[test]
fn test_generate_report_with_empty_tests() {
    // Arrange: Create detector with no tests
    let detector = FalsePositiveDetector::new(vec![]);
    let assertions = vec![];

    // Act: Generate report
    let report = detector
        .generate_report(&assertions)
        .expect("Failed to generate report");

    // Assert: Verify state - valid report with zero counts
    assert_eq!(report.total_tests_analyzed, 0, "Should have 0 tests");
    assert!(
        report.execution_only_tests.is_empty(),
        "Should have no false positives"
    );
}

/// Test: Severity calculation based on weak assertion percentage
#[test]
fn test_severity_calculation() {
    // Arrange: Create detector with 60% weak assertions
    let temp_dir = TempDir::new().expect("Failed to create temp dir");
    let detector = FalsePositiveDetector::new(vec![]);

    // 6 weak, 4 strong = 60% weak (should be CRITICAL)
    let mut assertions = vec![];
    for i in 0..6 {
        assertions.push(ggen_test_audit::TestAssertion {
            test_id: TestId::new(format!("weak_{}", i)).expect("Valid TestId"),
            file_path: temp_dir.path().join("test.rs"),
            assertion_strength: AssertionStrength::Weak,
            assertion_count: 1,
        });
    }
    for i in 0..4 {
        assertions.push(ggen_test_audit::TestAssertion {
            test_id: TestId::new(format!("strong_{}", i)).expect("Valid TestId"),
            file_path: temp_dir.path().join("test.rs"),
            assertion_strength: AssertionStrength::Strong,
            assertion_count: 1,
        });
    }

    // Act: Generate report
    let report = detector
        .generate_report(&assertions)
        .expect("Failed to generate report");

    // Assert: Verify severity - >50% weak should be CRITICAL
    assert_eq!(
        report.overall_severity,
        ggen_test_audit::Severity::Critical,
        "60% weak assertions should result in CRITICAL severity"
    );
}
