//! System profile tests

#[cfg(test)]
mod tests {
    use crate::profiling::system::SystemProfile;

    #[test]
    fn test_system_profile() {
        // Test that system profile detection works
        let profile = SystemProfile::detect().expect("System profile detection should work");

        // Check that all fields are populated with reasonable values
        assert!(!profile.hostname.is_empty(), "Hostname should not be empty");
        assert!(!profile.os_name.is_empty(), "OS name should not be empty");
        assert!(
            !profile.os_version.is_empty(),
            "OS version should not be empty"
        );
        assert!(
            !profile.kernel_version.is_empty(),
            "Kernel version should not be empty"
        );
        assert!(
            !profile.cpu_model.is_empty(),
            "CPU model should not be empty"
        );

        // CPU cores should be reasonable
        assert!(profile.cpu_cores >= 1, "Should have at least 1 CPU core");
        assert!(
            profile.cpu_threads >= profile.cpu_cores,
            "Threads should be >= cores"
        );

        // Memory should be reasonable (at least 1GB)
        assert!(
            profile.memory_total_bytes >= 1_000_000_000,
            "System should have at least 1GB memory"
        );

        // NUMA nodes should be None or a positive number
        if let Some(numa_nodes) = profile.numa_nodes {
            assert!(
                numa_nodes >= 1,
                "NUMA nodes should be at least 1 if present"
            );
        }
    }

    #[test]
    fn test_detect_numa_nodes() {
        // Test NUMA detection (this is platform-specific)
        let profile = SystemProfile::detect().expect("System profile detection should work");

        // On Linux, NUMA might be present
        // On macOS, NUMA should be None
        // On Windows, NUMA might be present

        // The test just verifies the function doesn't crash
        match profile.numa_nodes {
            Some(nodes) => {
                assert!(
                    nodes >= 1,
                    "If NUMA is detected, should have at least 1 node"
                );
                println!("NUMA nodes detected: {}", nodes);
            }
            None => {
                println!("NUMA not detected (normal for macOS/single-socket systems)");
            }
        }
    }

    #[test]
    fn test_get_total_memory() {
        // Test memory detection
        let profile = SystemProfile::detect().expect("System profile detection should work");

        // Memory should be a reasonable value
        assert!(
            profile.memory_total_bytes > 0,
            "Total memory should be positive"
        );

        // Should be at least 100MB (very conservative)
        assert!(
            profile.memory_total_bytes >= 100_000_000,
            "Total memory should be at least 100MB"
        );

        // Should be a reasonable amount (not more than 1TB for typical systems)
        assert!(
            profile.memory_total_bytes <= 1_000_000_000_000,
            "Total memory should be reasonable (<= 1TB)"
        );

        println!(
            "Total memory: {} MB",
            profile.memory_total_bytes / 1_000_000
        );
    }

    #[test]
    fn test_get_cpu_info() {
        // Test CPU information detection
        let profile = SystemProfile::detect().expect("System profile detection should work");

        // CPU model should be a recognizable string
        assert!(
            !profile.cpu_model.is_empty(),
            "CPU model should not be empty"
        );
        assert!(
            profile.cpu_model.len() >= 3,
            "CPU model should be at least 3 characters"
        );

        // Should contain common CPU manufacturer names
        let cpu_model_lower = profile.cpu_model.to_lowercase();
        let has_known_manufacturer = cpu_model_lower.contains("intel")
            || cpu_model_lower.contains("amd")
            || cpu_model_lower.contains("apple")
            || cpu_model_lower.contains("arm")
            || cpu_model_lower.contains("qualcomm");

        if !has_known_manufacturer {
            println!(
                "Note: CPU model doesn't contain known manufacturer: {}",
                profile.cpu_model
            );
        }

        // CPU cores and threads should be reasonable
        assert!(profile.cpu_cores >= 1, "CPU cores should be at least 1");
        assert!(profile.cpu_threads >= 1, "CPU threads should be at least 1");
        assert!(
            profile.cpu_threads >= profile.cpu_cores,
            "CPU threads should be >= cores"
        );

        // Should not exceed reasonable limits
        assert!(profile.cpu_cores <= 128, "CPU cores should not exceed 128");
        assert!(
            profile.cpu_threads <= 256,
            "CPU threads should not exceed 256"
        );

        println!(
            "CPU: {} ({} cores, {} threads)",
            profile.cpu_model, profile.cpu_cores, profile.cpu_threads
        );
    }

    #[test]
    fn test_get_os_info() {
        // Test OS information detection
        let profile = SystemProfile::detect().expect("System profile detection should work");

        // OS name should be a recognizable string
        assert!(!profile.os_name.is_empty(), "OS name should not be empty");
        assert!(
            profile.os_name.len() >= 2,
            "OS name should be at least 2 characters"
        );

        // Should contain known OS names
        let os_name_lower = profile.os_name.to_lowercase();
        let has_known_os = os_name_lower.contains("linux")
            || os_name_lower.contains("macos")
            || os_name_lower.contains("darwin")
            || os_name_lower.contains("windows");

        assert!(
            has_known_os,
            "OS name should contain known OS: {}",
            profile.os_name
        );

        // OS version should be present
        assert!(
            !profile.os_version.is_empty(),
            "OS version should not be empty"
        );
        assert!(
            profile.os_version.len() >= 1,
            "OS version should have at least 1 character"
        );

        // Kernel version should be present
        assert!(
            !profile.kernel_version.is_empty(),
            "Kernel version should not be empty"
        );
        assert!(
            profile.kernel_version.len() >= 1,
            "Kernel version should have at least 1 character"
        );

        println!(
            "OS: {} {} (kernel: {})",
            profile.os_name, profile.os_version, profile.kernel_version
        );
    }

    #[test]
    fn test_system_profile_consistency() {
        // Test that multiple calls produce consistent results
        let profile1 = SystemProfile::detect().expect("First system profile detection should work");
        let profile2 =
            SystemProfile::detect().expect("Second system profile detection should work");

        // Most fields should be the same between calls
        assert_eq!(
            profile1.hostname, profile2.hostname,
            "Hostname should be consistent"
        );
        assert_eq!(
            profile1.os_name, profile2.os_name,
            "OS name should be consistent"
        );
        assert_eq!(
            profile1.os_version, profile2.os_version,
            "OS version should be consistent"
        );
        assert_eq!(
            profile1.kernel_version, profile2.kernel_version,
            "Kernel version should be consistent"
        );
        assert_eq!(
            profile1.cpu_model, profile2.cpu_model,
            "CPU model should be consistent"
        );
        assert_eq!(
            profile1.cpu_cores, profile2.cpu_cores,
            "CPU cores should be consistent"
        );
        assert_eq!(
            profile1.cpu_threads, profile2.cpu_threads,
            "CPU threads should be consistent"
        );
        assert_eq!(
            profile1.memory_total_bytes, profile2.memory_total_bytes,
            "Total memory should be consistent"
        );
        assert_eq!(
            profile1.numa_nodes, profile2.numa_nodes,
            "NUMA nodes should be consistent"
        );
    }
}
