//! Baseline comparison

use super::builder::BenchmarkReport;

/// Comparison between benchmark reports
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ComparisonResult {
    pub timestamp: String,
    pub network_delta_percent: Option<f64>,
    pub disk_delta_percent: Option<f64>,
    pub memory_delta_percent: Option<f64>,
    pub cpu_delta_percent: Option<f64>,
    pub regressions: Vec<String>,
    pub improvements: Vec<String>,
    pub schema_compatible: bool,
    pub warnings: Vec<String>,
}

/// Compare two benchmark reports
pub fn compare_baselines(
    current: &BenchmarkReport,
    baseline: &BenchmarkReport,
) -> ComparisonResult {
    let mut regressions = Vec::new();
    let mut improvements = Vec::new();
    let mut warnings = Vec::new();

    // Check schema version compatibility
    let schema_compatible = current.schema_version == baseline.schema_version;
    if !schema_compatible {
        warnings.push(format!(
            "Schema version mismatch: current={}, baseline={}. Results may not be comparable.",
            current.schema_version, baseline.schema_version
        ));
    }

    // Check for invalid reports
    if current.schema_version == "ERROR" {
        warnings.push("Current report failed to load".to_string());
    }
    if baseline.schema_version == "ERROR" {
        warnings.push("Baseline report failed to load".to_string());
    }

    // Network comparison
    let network_delta =
        if !current.network_results.is_empty() && !baseline.network_results.is_empty() {
            let current_bw = current.network_results[0].bandwidth_bps;
            let baseline_bw = baseline.network_results[0].bandwidth_bps;
            let delta = ((current_bw - baseline_bw) / baseline_bw) * 100.0;

            if delta < -5.0 {
                regressions.push(format!(
                    "Network bandwidth decreased by {:.1}%",
                    delta.abs()
                ));
            } else if delta > 5.0 {
                improvements.push(format!("Network bandwidth increased by {:.1}%", delta));
            }

            Some(delta)
        } else {
            None
        };

    // Disk comparison
    let disk_delta = if !current.disk_results.is_empty() && !baseline.disk_results.is_empty() {
        let current_bw = current.disk_results[0].sequential_read.throughput_mbps;
        let baseline_bw = baseline.disk_results[0].sequential_read.throughput_mbps;
        let delta = ((current_bw - baseline_bw) / baseline_bw) * 100.0;

        if delta < -5.0 {
            regressions.push(format!("Disk throughput decreased by {:.1}%", delta.abs()));
        } else if delta > 5.0 {
            improvements.push(format!("Disk throughput increased by {:.1}%", delta));
        }

        Some(delta)
    } else {
        None
    };

    // Memory comparison
    let memory_delta = if !current.memory_results.is_empty() && !baseline.memory_results.is_empty()
    {
        let current_bw = current.memory_results[0].read_bandwidth_gbps;
        let baseline_bw = baseline.memory_results[0].read_bandwidth_gbps;
        let delta = ((current_bw - baseline_bw) / baseline_bw) * 100.0;

        if delta < -5.0 {
            regressions.push(format!("Memory bandwidth decreased by {:.1}%", delta.abs()));
        } else if delta > 5.0 {
            improvements.push(format!("Memory bandwidth increased by {:.1}%", delta));
        }

        Some(delta)
    } else {
        None
    };

    // CPU comparison
    let cpu_delta = if !current.cpu_results.is_empty() && !baseline.cpu_results.is_empty() {
        let current_score = current.cpu_results[0].single_thread.combined_score;
        let baseline_score = baseline.cpu_results[0].single_thread.combined_score;
        let delta = ((current_score - baseline_score) / baseline_score) * 100.0;

        if delta < -5.0 {
            regressions.push(format!("CPU performance decreased by {:.1}%", delta.abs()));
        } else if delta > 5.0 {
            improvements.push(format!("CPU performance increased by {:.1}%", delta));
        }

        Some(delta)
    } else {
        None
    };

    ComparisonResult {
        timestamp: chrono::Utc::now().to_rfc3339(),
        network_delta_percent: network_delta,
        disk_delta_percent: disk_delta,
        memory_delta_percent: memory_delta,
        cpu_delta_percent: cpu_delta,
        regressions,
        improvements,
        schema_compatible,
        warnings,
    }
}
