use crate::Span;

/// Severity level for a diagnostic.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Level {
    /// A problem that prevents the current pipeline stage from succeeding.
    Error,
    /// A non-fatal issue.
    Warning,
}

/// Stable machine-readable diagnostic code.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ErrorCode {
    /// A block name is not registered in the [`crate::Forge`].
    UnknownBlock,
    /// An inline name is not registered in the [`crate::Forge`].
    UnknownInline,
    /// A required argument was omitted.
    MissingRequiredArg,
    /// An argument was supplied but not defined by the extension spec.
    UnknownArg,
    /// A value could not be interpreted as the expected type.
    InvalidType,
    /// A value is not in a static enum's allowed set.
    InvalidStaticEnumValue,
    /// A value is not in a runtime dynamic enum's allowed set.
    InvalidDynamicEnumValue,
    /// A block opening line did not have a matching closing `:::` line.
    BlockNotClosed,
}

/// Structured feedback returned by parse, validation, evaluation, and rendering.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Diagnostic {
    /// Diagnostic severity.
    pub level: Level,
    /// Stable diagnostic code.
    pub code: ErrorCode,
    /// Human-readable message.
    pub message: String,
    /// Source location associated with the diagnostic.
    pub span: Span,
    /// Optional user-facing repair hint.
    pub suggestion: Option<String>,
}
