//! Error types for tsafe-core.
//!
//! All fallible public functions return [`SafeResult<T>`], which is an alias for
//! `Result<T, SafeError>`.  Callers can match on specific variants for structured
//! error handling or surface the `Display` message (derived by `thiserror`) for
//! user-facing output.

use thiserror::Error;

/// Top-level error type for all tsafe-core operations.
#[derive(Debug, Error)]
pub enum SafeError {
    #[error("vault not found: {path}")]
    VaultNotFound { path: String },

    #[error("vault already exists: {path}")]
    VaultAlreadyExists { path: String },

    #[error("secret not found: {key}")]
    SecretNotFound { key: String },

    #[error("secret already exists: {key}")]
    SecretAlreadyExists { key: String },

    #[error("profile not found: {name}")]
    ProfileNotFound { name: String },

    #[error("decryption failed — wrong password or corrupted vault")]
    DecryptionFailed,

    #[error("crypto error: {context}")]
    Crypto { context: String },

    #[error("invalid vault: {reason}")]
    InvalidVault { reason: String },

    #[error("import parse error in {file}: {reason}")]
    ImportParse { file: String, reason: String },

    #[error("no snapshots available to restore profile '{profile}'")]
    NoSnapshotAvailable { profile: String },

    #[error("snapshot not found: {path}")]
    SnapshotNotFound { path: String },

    #[error("vault schema migration failed: {reason}")]
    MigrationFailed { reason: String },

    #[error("vault is corrupted and could not be auto-healed: {reason}")]
    VaultCorrupted { reason: String },

    /// The OS credential store entry for biometric/keyring unlock is stale.
    ///
    /// This occurs when the vault password was rotated, a new fingerprint enrolled,
    /// or the biometric enrollment changed after `tsafe biometric enable` was run.
    /// The stored credential no longer matches — the user must re-enroll explicitly.
    ///
    /// Callers MUST NOT silently fall through to another method. Surface this
    /// error with a clear message directing the user to `tsafe biometric re-enroll`.
    #[error(
        "stale biometric credential: the stored credential no longer matches the vault (password \
         was rotated or biometric enrollment changed). Run `tsafe biometric re-enroll` to \
         restore password-free unlock."
    )]
    StaleBiometricCredential,

    /// The Windows Hello verification dialog was dismissed by the user before
    /// completing. The vault unlock is not permitted; the caller must not fall
    /// through to another unlock method.
    #[error("Windows Hello verification was canceled by the user")]
    BiometricCanceled,

    /// A Windows Hello verification attempt failed for a reason other than
    /// user cancellation (device not ready, OS error, etc.).
    #[error("Windows Hello verification failed: {0}")]
    BiometricFailed(String),

    #[error("io error: {0}")]
    Io(#[from] std::io::Error),

    #[error("serialization error: {0}")]
    Serialization(#[from] serde_json::Error),
}

/// Convenience alias for `Result<T, SafeError>`.
pub type SafeResult<T> = Result<T, SafeError>;
