//! Error types for chainfire-core

use thiserror::Error;

/// Result type for chainfire-core operations
pub type Result<T> = std::result::Result<T, ClusterError>;

/// Errors that can occur in cluster operations
#[derive(Debug, Error)]
pub enum ClusterError {
    /// Storage operation failed
    #[error("storage error: {0}")]
    Storage(String),

    /// Raft consensus error
    #[error("raft error: {0}")]
    Raft(String),

    /// Gossip protocol error
    #[error("gossip error: {0}")]
    Gossip(String),

    /// Network error
    #[error("network error: {0}")]
    Network(String),

    /// Configuration error
    #[error("configuration error: {0}")]
    Config(String),

    /// Not the leader - write operations must go to leader
    #[error("not the leader, current leader is: {leader_id:?}")]
    NotLeader {
        /// Current leader's node ID, if known
        leader_id: Option<u64>,
    },

    /// Key not found
    #[error("key not found")]
    KeyNotFound,

    /// Compare-and-swap version mismatch
    #[error("version mismatch: expected {expected}, got {actual}")]
    VersionMismatch {
        /// Expected version
        expected: u64,
        /// Actual version
        actual: u64,
    },

    /// Cluster not initialized
    #[error("cluster not initialized")]
    NotInitialized,

    /// Node already exists in cluster
    #[error("node {0} already exists in cluster")]
    NodeExists(u64),

    /// Node not found in cluster
    #[error("node {0} not found in cluster")]
    NodeNotFound(u64),

    /// Operation timed out
    #[error("operation timed out")]
    Timeout,

    /// Cluster is shutting down
    #[error("cluster is shutting down")]
    ShuttingDown,

    /// Internal error
    #[error("internal error: {0}")]
    Internal(String),

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