//! Error types for samaharam.

use thiserror::Error;

use crate::registry::VkId;

/// Main error type for samaharam operations.
#[derive(Error, Debug)]
pub enum Error {
    /// Verification key not found in registry
    #[error("verification key {0:?} not found in registry")]
    UnknownVk(VkId),

    /// Proof verification failed
    #[error("proof verification failed: {0}")]
    VerificationFailed(String),

    /// Batch size exceeded maximum
    #[error("batch size {got} exceeds maximum {max}")]
    BatchTooLarge { got: usize, max: usize },

    /// Batch is empty
    #[error("cannot aggregate empty batch")]
    EmptyBatch,

    /// Public input count mismatch
    #[error("public input count mismatch: expected {expected}, got {got}")]
    PublicInputMismatch { expected: usize, got: usize },

    /// SRS size insufficient
    #[error("SRS size {srs_k} too small for circuit size {circuit_k}")]
    InsufficientSrs { srs_k: u32, circuit_k: u32 },

    /// IO error
    #[error(transparent)]
    Io(#[from] std::io::Error),

    /// Serialization error
    #[error(transparent)]
    Serialization(#[from] bincode::Error),
}

/// Configuration error type.
#[derive(Error, Debug)]
pub enum ConfigError {
    /// SRS not provided
    #[error("SRS not provided in configuration")]
    MissingSrs,

    /// Invalid batch size
    #[error("batch size must be positive, got {0}")]
    InvalidBatchSize(usize),
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn error_display_unknown_vk() {
        let err = Error::UnknownVk(VkId::new(42));
        assert!(err.to_string().contains("42"));
    }

    #[test]
    fn error_display_batch_too_large() {
        let err = Error::BatchTooLarge { got: 100, max: 32 };
        assert!(err.to_string().contains("100"));
        assert!(err.to_string().contains("32"));
    }

    #[test]
    fn config_error_display() {
        let err = ConfigError::MissingSrs;
        assert!(err.to_string().contains("SRS"));
    }
}
