//! `VlmAssessment` — per `data_model.md §2 Perception entities`.
//!
//! Status semantics: any value other than `Ok` MUST produce
//! `label = Inconclusive` (or `Error` for a critical failure). The
//! `scan_controller` MUST NOT promote a POI to a confirmed target on a non-`Ok`
//! `VlmAssessment`.

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum VlmLabel {
    ConfirmedConcealedPosition,
    Rejected,
    Inconclusive,
    Error,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum VlmStatus {
    Ok,
    Timeout,
    SchemaInvalid,
    IpcError,
    Disabled,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VlmAssessment {
    pub label: VlmLabel,
    pub confidence: f32,
    pub evidence_spans: Vec<String>,
    pub reason: String,
    pub status: VlmStatus,
    pub latency_ms: u32,
    pub model_version: String,
}

impl VlmAssessment {
    /// The `vlm_disabled` no-op assessment returned by the default
    /// `VlmProvider` impl when the binary is built without `--features vlm`
    /// or `vlm.enabled = false` in config.
    pub fn disabled() -> Self {
        Self {
            label: VlmLabel::Inconclusive,
            confidence: 0.0,
            evidence_spans: Vec::new(),
            reason: "vlm disabled".into(),
            status: VlmStatus::Disabled,
            latency_ms: 0,
            model_version: String::new(),
        }
    }
}
