use crate::monitor::andon::AlertLevel;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EmergencyCondition {
CollisionImminent {
time_to_collision_ms: f32,
},
SensorDegraded {
sensor: String,
quality: f32,
},
AuditChainBroken,
DecisionTimeout {
max_ms: f32,
},
ConsecutiveLowConfidence {
count: usize,
threshold: f32,
},
InvalidOutput,
}
impl EmergencyCondition {
pub fn alert_level(&self) -> AlertLevel {
match self {
EmergencyCondition::CollisionImminent { .. } => AlertLevel::Critical,
EmergencyCondition::SensorDegraded { quality, .. } if *quality < 0.3 => {
AlertLevel::Critical
}
EmergencyCondition::SensorDegraded { .. } => AlertLevel::Error,
EmergencyCondition::AuditChainBroken => AlertLevel::Critical,
EmergencyCondition::DecisionTimeout { .. } => AlertLevel::Error,
EmergencyCondition::ConsecutiveLowConfidence { .. } => AlertLevel::Warning,
EmergencyCondition::InvalidOutput => AlertLevel::Critical,
}
}
pub fn message(&self) -> String {
match self {
EmergencyCondition::CollisionImminent { time_to_collision_ms } => {
format!("Collision imminent in {time_to_collision_ms:.1}ms")
}
EmergencyCondition::SensorDegraded { sensor, quality } => {
let quality_pct = quality * 100.0;
format!("Sensor {sensor} degraded: quality={quality_pct:.1}%")
}
EmergencyCondition::AuditChainBroken => "Audit chain integrity failure".to_string(),
EmergencyCondition::DecisionTimeout { max_ms } => {
format!("Decision timeout: exceeded {max_ms:.1}ms limit")
}
EmergencyCondition::ConsecutiveLowConfidence { count, threshold } => {
let threshold_pct = threshold * 100.0;
format!("{count} consecutive decisions below {threshold_pct:.1}% confidence")
}
EmergencyCondition::InvalidOutput => "NaN or Inf detected in model output".to_string(),
}
}
}