/// Typed errors for brainharmony.
///
/// All public APIs return `Result<T, BrainHarmonyError>` (or `anyhow::Result`
/// for the CLI).  Match on the variant to handle specific failure modes.
use std::path::PathBuf;

#[derive(Debug, thiserror::Error)]
pub enum BrainHarmonyError {
    // -- Config -------------------------------------------------------------------

    #[error("unknown model variant \"{name}\" (expected vit_small, vit_base, or vit_large)")]
    UnknownVariant { name: String },

    #[error("invalid positional embedding mode \"{mode}\" (expected \"gradient_geoh\" or \"sincos\")")]
    InvalidPosMode { mode: String },

    // -- Files --------------------------------------------------------------------

    #[error("{kind} file not found: {path}")]
    FileNotFound { kind: &'static str, path: PathBuf },

    // -- Data ---------------------------------------------------------------------

    #[error("CSV is empty or contains no valid rows: {path}")]
    EmptyCsv { path: PathBuf },

    #[error(
        "CSV row {row} has {got} columns, expected {expected} (file: {path})"
    )]
    InconsistentCsvRow {
        path: PathBuf,
        row: usize,
        expected: usize,
        got: usize,
    },

    #[error("gradient CSV has {got} ROIs, expected {expected}")]
    GradientRoiMismatch { expected: usize, got: usize },

    #[error("geometric harmonics CSV has {got} ROIs, expected {expected}")]
    GeohRoiMismatch { expected: usize, got: usize },

    #[error("token count {got} exceeds maximum {max}")]
    TokenCountExceeded { got: usize, max: usize },

    // -- Weights ------------------------------------------------------------------

    #[error("weight key not found: {key}")]
    WeightKeyMissing { key: String },

    // -- Tensor -------------------------------------------------------------------

    #[error("tensor conversion failed: {reason}")]
    TensorConversion { reason: String },

    // -- Pass-through -------------------------------------------------------------

    #[error(transparent)]
    Io(#[from] std::io::Error),

    #[error(transparent)]
    Other(#[from] anyhow::Error),
}

/// Convenience alias used throughout the crate.
pub type Result<T> = std::result::Result<T, BrainHarmonyError>;
