#[derive(Debug, thiserror::Error)]
pub enum KontorPoRError {
#[error("Merkle tree error: {0}")]
MerkleTree(String),
#[error("Circuit error: {0}")]
Circuit(String),
#[error("SNARK error: {0}")]
Snark(String),
#[error("Invalid input: {0}")]
InvalidInput(String),
#[error("Empty data: {operation} requires non-empty input data")]
EmptyData { operation: String },
#[error("Too many files: {got} exceeds limit of {max}")]
TooManyFiles { got: usize, max: usize },
#[error("File not found: {file_id}")]
FileNotFound { file_id: String },
#[error("File not in ledger: {file_id} (possible depth spoofing)")]
FileNotInLedger { file_id: String },
#[error("Challenge mismatch: {field} values must be consistent across all challenges")]
ChallengeMismatch { field: String },
#[error("Invalid challenge count: {count} (must be > 0 and <= {max})", max = crate::config::MAX_NUM_CHALLENGES)]
InvalidChallengeCount { count: usize },
#[error("Invalid chunk size: {size} bytes (must be > 0 and ≤ {max})")]
InvalidChunkSize { size: usize, max: usize },
#[error("Metadata mismatch: file root does not match expected value")]
MetadataMismatch,
#[error("Erasure coding error: {details}")]
ErasureCoding { details: String },
#[error("Ledger validation failed: {reason}")]
LedgerValidation { reason: String },
#[error("Cryptographic error: {0}")]
Cryptographic(String),
#[error("Serialization error: {0}")]
Serialization(String),
#[error("IO error: {0}")]
IO(String),
#[error("Index out of bounds: index {index}, length {length}")]
IndexOutOfBounds { index: usize, length: usize },
#[error("Invalid chunk encoding: chunk size {size} bytes exceeds maximum {max} bytes")]
InvalidChunkEncoding { size: usize, max: usize },
}
pub type Result<T> = std::result::Result<T, KontorPoRError>;