//! Sanity checks for benchmark results

use super::config::global_config_or_default;
use super::error::ProfilingError;

/// Sanity check validation for benchmark results
pub struct SanityChecker;

impl SanityChecker {
    /// Check network result for anomalies
    pub fn check_network_result(bandwidth_bps: f64) -> Result<(), ProfilingError> {
        if bandwidth_bps < 0.0 {
            return Err(ProfilingError::ParseError(
                "Negative bandwidth detected - invalid result".to_string(),
            ));
        }

        if bandwidth_bps == 0.0 {
            super::logging::log_warn("Zero bandwidth detected - possible network issue");
            return Ok(());
        }

        let config = global_config_or_default();
        let max_bandwidth = config.max_network_bandwidth_gbps * 1_000_000_000.0;

        if bandwidth_bps > max_bandwidth {
            return Err(ProfilingError::ParseError(format!(
                "Bandwidth {:.2} Gbps exceeds configured maximum {:.2} Gbps",
                bandwidth_bps / 1_000_000_000.0,
                config.max_network_bandwidth_gbps
            )));
        }

        // Warn about suspiciously low bandwidth
        if bandwidth_bps < 1_000_000.0 {
            super::logging::log_warn(&format!(
                "Very low bandwidth detected: {:.2} Mbps - possible network congestion",
                bandwidth_bps / 1_000_000.0
            ));
        }

        Ok(())
    }

    /// Check disk result for anomalies
    pub fn check_disk_result(throughput_mbps: f64) -> Result<(), ProfilingError> {
        if throughput_mbps < 0.0 {
            return Err(ProfilingError::ParseError(
                "Negative throughput detected - invalid result".to_string(),
            ));
        }

        if throughput_mbps == 0.0 {
            super::logging::log_warn("Zero disk throughput detected - possible storage issue");
            return Ok(());
        }

        let config = global_config_or_default();
        let max_throughput = config.max_disk_throughput_mbps;

        if throughput_mbps > max_throughput {
            return Err(ProfilingError::ParseError(format!(
                "Disk throughput {:.2} MB/s exceeds configured maximum {:.2} MB/s",
                throughput_mbps, max_throughput
            )));
        }

        // Warn about suspiciously low throughput
        if throughput_mbps < 10.0 {
            super::logging::log_warn(&format!(
                "Very low disk throughput detected: {:.2} MB/s - possible storage bottleneck",
                throughput_mbps
            ));
        }

        Ok(())
    }

    /// Check memory result for anomalies
    pub fn check_memory_result(bandwidth_gbps: f64) -> Result<(), ProfilingError> {
        if bandwidth_gbps < 0.0 {
            return Err(ProfilingError::ParseError(
                "Negative memory bandwidth detected - invalid result".to_string(),
            ));
        }

        if bandwidth_gbps == 0.0 {
            super::logging::log_warn("Zero memory bandwidth detected - possible memory issue");
            return Ok(());
        }

        let config = global_config_or_default();
        let max_bandwidth = config.max_memory_bandwidth_gbps;

        if bandwidth_gbps > max_bandwidth {
            return Err(ProfilingError::ParseError(format!(
                "Memory bandwidth {:.2} GB/s exceeds configured maximum {:.2} GB/s",
                bandwidth_gbps, max_bandwidth
            )));
        }

        // Warn about suspiciously low bandwidth
        if bandwidth_gbps < 1.0 {
            super::logging::log_warn(&format!(
                "Very low memory bandwidth detected: {:.2} GB/s - possible memory bottleneck",
                bandwidth_gbps
            ));
        }

        Ok(())
    }

    /// Check CPU result for anomalies
    pub fn check_cpu_result(score: f64) -> Result<(), ProfilingError> {
        if score < 0.0 {
            return Err(ProfilingError::ParseError(
                "Negative CPU score detected - invalid result".to_string(),
            ));
        }

        if score == 0.0 {
            super::logging::log_warn("Zero CPU score detected - possible CPU throttling or issue");
            return Ok(());
        }

        let config = global_config_or_default();
        let max_score = config.max_cpu_score;

        if score > max_score {
            return Err(ProfilingError::ParseError(format!(
                "CPU score {:.0} exceeds configured maximum {:.0}",
                score, max_score
            )));
        }

        // Warn about suspiciously low score
        if score < 100.0 {
            super::logging::log_warn(&format!(
                "Very low CPU score detected: {:.0} - possible CPU throttling or system load",
                score
            ));
        }

        Ok(())
    }

    /// Check latency for anomalies
    pub fn check_latency(latency_ns: f64) -> Result<(), ProfilingError> {
        if latency_ns < 0.0 {
            return Err(ProfilingError::ParseError(
                "Negative latency detected - invalid result".to_string(),
            ));
        }

        if latency_ns > 1_000_000_000.0 {
            // 1 second
            return Err(ProfilingError::ParseError(
                "Latency exceeds realistic maximum - possible measurement error".to_string(),
            ));
        }

        // Warn about suspiciously high latency
        if latency_ns > 100_000_000.0 {
            // 100ms
            super::logging::log_warn(&format!(
                "High latency detected: {:.2} ms - possible network congestion",
                latency_ns / 1_000_000.0
            ));
        }

        Ok(())
    }

    /// Check IOPS for anomalies
    pub fn check_iops(iops: f64) -> Result<(), ProfilingError> {
        if iops < 0.0 {
            return Err(ProfilingError::ParseError(
                "Negative IOPS detected - invalid result".to_string(),
            ));
        }

        if iops == 0.0 {
            super::logging::log_warn("Zero IOPS detected - possible storage issue");
            return Ok(());
        }

        let config = global_config_or_default();
        let max_iops = config.max_disk_iops;

        if iops > max_iops {
            return Err(ProfilingError::ParseError(format!(
                "IOPS {:.0} exceeds configured maximum {:.0}",
                iops, max_iops
            )));
        }

        // Warn about suspiciously low IOPS
        if iops < 100.0 {
            super::logging::log_warn(&format!(
                "Very low IOPS detected: {:.0} - possible storage bottleneck",
                iops
            ));
        }

        Ok(())
    }

    /// Check temperature for anomalies
    pub fn check_temperature(celsius: f64) -> Result<(), ProfilingError> {
        if celsius < 0.0 {
            return Err(ProfilingError::ParseError(
                "Negative temperature detected - invalid result".to_string(),
            ));
        }

        if celsius > 150.0 {
            return Err(ProfilingError::ParseError(
                "Temperature exceeds safe operating limits".to_string(),
            ));
        }

        // Warn about high temperature
        if celsius > 85.0 {
            super::logging::log_warn(&format!(
                "High temperature detected: {:.1}°C - possible thermal throttling",
                celsius
            ));
        }

        Ok(())
    }
}
