use crate::engine::models::{BufferbloatGrade, TestReport};
const MBPS: f64 = 1_000_000.0;
#[must_use]
pub fn verdict(report: &TestReport) -> String {
let down = report.download.average_bps / MBPS;
let up = report.upload.average_bps / MBPS;
let ping = report.latency.average_ms;
let bloat = report.bufferbloat.map(|b| b.grade);
let mut clauses: Vec<String> = Vec::new();
clauses.push(match down {
d if d >= 75.0 => "Great for 4K streaming on several devices".to_owned(),
d if d >= 25.0 => "Good for 4K streaming".to_owned(),
d if d >= 10.0 => "Good for HD streaming".to_owned(),
d if d >= 3.0 => "OK for SD streaming; HD may buffer".to_owned(),
_ => "Too slow for smooth video streaming".to_owned(),
});
let calls_bandwidth = down >= 3.5 && up >= 3.5;
let calls_stable = !matches!(
bloat,
Some(BufferbloatGrade::C | BufferbloatGrade::D | BufferbloatGrade::F)
);
clauses.push(match (calls_bandwidth, calls_stable) {
(true, true) => "video calls should be smooth".to_owned(),
(true, false) => "video calls may stutter while others use the connection".to_owned(),
(false, _) => "upload is tight for video calls".to_owned(),
});
let gaming = match ping {
p if p < 60.0 => Some("responsive for online gaming"),
p if p < 110.0 => Some("playable for casual gaming"),
_ => Some("high ping for fast-paced gaming"),
};
if let Some(gaming) = gaming {
let suffix = match bloat {
Some(BufferbloatGrade::D | BufferbloatGrade::F) => {
" (expect lag spikes during downloads)"
}
_ => "",
};
clauses.push(format!("{gaming}{suffix}"));
}
clauses.join(" · ")
}