//! Library error type (`thiserror`; no `anyhow` in the public API).

use uuid::Uuid;

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

/// Everything that can go wrong inside grit-core.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
    /// Underlying SQLite failure.
    #[error("sqlite: {0}")]
    Sqlite(#[from] rusqlite::Error),

    /// Op or attribute JSON failed to (de)serialize.
    #[error("json: {0}")]
    Json(#[from] serde_json::Error),

    /// Filesystem failure (export/import).
    #[error("io: {0}")]
    Io(#[from] std::io::Error),

    /// The writer actor has shut down; the handle is unusable.
    #[error("grit writer is closed")]
    Closed,

    /// A referenced node/edge/episode does not exist.
    #[error("not found: {0}")]
    NotFound(Uuid),

    /// A stored HLC string failed to parse.
    #[error("invalid hlc: {0}")]
    InvalidHlc(String),

    /// The database schema version is newer than this library understands.
    /// Migrations are forward-only (Design Invariant 8).
    #[error("db schema version {found} is newer than supported version {supported}")]
    SchemaTooNew {
        /// `PRAGMA user_version` found in the file.
        found: i64,
        /// Latest version this build can open.
        supported: i64,
    },

    /// An op is structurally invalid (e.g. merging a node into itself).
    #[error("invalid op: {0}")]
    InvalidOp(String),

    /// Embedding operations before `register_embedding_model`, or a dimension
    /// mismatch against the registered model.
    #[error("embedding: {0}")]
    Embedding(String),

    /// An import line could not be understood.
    #[error("import: {0}")]
    Import(String),

    /// A stored row failed to decode (e.g. a malformed uuid) — the database
    /// contains data grit did not write. Surfaced loudly rather than silently
    /// dropping the row.
    #[error("corrupt row: {0}")]
    Corrupt(String),
}
