//! Monitor module tests

#[cfg(test)]
mod tests {
    use crate::profiling::monitor::{
        cpu::sample_cpu_utilization, memory::sample_memory_usage, resource_monitor,
    };

    #[test]
    fn test_sample_cpu_utilization() {
        // Test that CPU sampling returns a valid value
        let cpu_usage = sample_cpu_utilization();

        // Should be between 0.0 and 1.0
        assert!(cpu_usage >= 0.0, "CPU usage should not be negative");
        assert!(cpu_usage <= 1.0, "CPU usage should not exceed 100%");

        // Should be a reasonable value (not NaN or infinite)
        assert!(cpu_usage.is_finite(), "CPU usage should be a finite number");
    }

    #[test]
    fn test_sample_memory_usage_percent() {
        // Test that memory sampling returns valid percentage
        let (percent, used, total) = sample_memory_usage();

        // Percentage should be between 0 and 100
        assert!(percent >= 0.0, "Memory percentage should not be negative");
        assert!(percent <= 100.0, "Memory percentage should not exceed 100%");

        // Used bytes should be reasonable
        assert!(used > 0, "Memory used should be positive");
        assert!(used <= total, "Memory used should not exceed total");

        // Total bytes should be reasonable
        assert!(total > 0, "Total memory should be positive");
        assert!(total >= used, "Total memory should be at least used memory");

        // Values should be finite
        assert!(percent.is_finite(), "Memory percentage should be finite");
    }

    #[test]
    fn test_sample_memory_usage_bytes() {
        // Test that memory byte values are reasonable
        let (_, used, total) = sample_memory_usage();

        // Check that values are in reasonable ranges (assuming at least 1GB system)
        assert!(
            total >= 1_000_000_000,
            "Total memory should be at least 1GB"
        );

        // Used memory should be less than total but reasonable
        assert!(used >= 100_000_000, "Used memory should be at least 100MB");
        assert!(used <= total, "Used memory should not exceed total");
    }

    #[test]
    fn test_resource_monitor() {
        // Test the resource monitor function
        let sample = resource_monitor();

        // Check that sample has valid fields
        assert!(
            !sample.timestamp.is_empty(),
            "Timestamp should not be empty"
        );

        // CPU should be between 0 and 100
        assert!(
            sample.cpu_percent >= 0.0,
            "CPU percent should not be negative"
        );
        assert!(
            sample.cpu_percent <= 100.0,
            "CPU percent should not exceed 100"
        );

        // Memory should be between 0 and 100
        assert!(
            sample.memory_percent >= 0.0,
            "Memory percent should not be negative"
        );
        assert!(
            sample.memory_percent <= 100.0,
            "Memory percent should not exceed 100"
        );

        // Memory bytes should be reasonable
        assert!(
            sample.memory_used_bytes > 0,
            "Memory used bytes should be positive"
        );
        assert!(
            sample.memory_total_bytes > 0,
            "Memory total bytes should be positive"
        );
        assert!(
            sample.memory_used_bytes <= sample.memory_total_bytes,
            "Used memory should not exceed total"
        );

        // I/O metrics should be reasonable
        assert!(
            sample.io_wait_percent >= 0.0,
            "I/O wait should not be negative"
        );
        assert!(
            sample.io_queue_depth >= 0.0,
            "I/O queue depth should not be negative"
        );

        // All numeric values should be finite
        assert!(
            sample.cpu_percent.is_finite(),
            "CPU percent should be finite"
        );
        assert!(
            sample.memory_percent.is_finite(),
            "Memory percent should be finite"
        );
        assert!(
            sample.io_wait_percent.is_finite(),
            "I/O wait should be finite"
        );
        assert!(
            sample.io_queue_depth.is_finite(),
            "I/O queue depth should be finite"
        );
    }

    #[test]
    fn test_resource_monitor_consistency() {
        // Test that resource monitor provides consistent data
        let sample1 = resource_monitor();
        std::thread::sleep(std::time::Duration::from_millis(250));
        let sample2 = resource_monitor();

        // Timestamps should be different
        assert_ne!(
            sample1.timestamp, sample2.timestamp,
            "Timestamps should be different for different samples"
        );

        // Memory total should be the same (system memory doesn't change)
        assert_eq!(
            sample1.memory_total_bytes, sample2.memory_total_bytes,
            "Total memory should be constant"
        );

        // Values should be in reasonable ranges
        for sample in [sample1, sample2] {
            assert!(sample.cpu_percent >= 0.0 && sample.cpu_percent <= 100.0);
            assert!(sample.memory_percent >= 0.0 && sample.memory_percent <= 100.0);
            assert!(sample.memory_used_bytes > 0);
            assert!(sample.memory_total_bytes > 0);
        }
    }
}
