//! Error types for Synor Storage

use std::fmt;

/// Result type for storage operations
pub type Result<T> = std::result::Result<T, Error>;

/// Storage layer errors
#[derive(Debug)]
pub enum Error {
    /// Content not found
    NotFound(String),
    /// Invalid CID format
    InvalidCid(String),
    /// Chunk reassembly failed
    ReassemblyFailed(String),
    /// Erasure coding error
    ErasureCoding(String),
    /// Storage proof verification failed
    ProofVerificationFailed(String),
    /// Deal not found or invalid
    InvalidDeal(String),
    /// Insufficient storage capacity
    InsufficientCapacity,
    /// Network error
    Network(String),
    /// I/O error
    Io(std::io::Error),
    /// Serialization error
    Serialization(String),
    /// Internal error
    Internal(String),
}

impl std::error::Error for Error {}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::NotFound(msg) => write!(f, "Content not found: {}", msg),
            Self::InvalidCid(msg) => write!(f, "Invalid CID: {}", msg),
            Self::ReassemblyFailed(msg) => write!(f, "Chunk reassembly failed: {}", msg),
            Self::ErasureCoding(msg) => write!(f, "Erasure coding error: {}", msg),
            Self::ProofVerificationFailed(msg) => write!(f, "Proof verification failed: {}", msg),
            Self::InvalidDeal(msg) => write!(f, "Invalid deal: {}", msg),
            Self::InsufficientCapacity => write!(f, "Insufficient storage capacity"),
            Self::Network(msg) => write!(f, "Network error: {}", msg),
            Self::Io(e) => write!(f, "I/O error: {}", e),
            Self::Serialization(msg) => write!(f, "Serialization error: {}", msg),
            Self::Internal(msg) => write!(f, "Internal error: {}", msg),
        }
    }
}

impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Self {
        Self::Io(e)
    }
}

impl From<serde_json::Error> for Error {
    fn from(e: serde_json::Error) -> Self {
        Self::Serialization(e.to_string())
    }
}
