//! Error types for the iddrop protocol-engine.

use thiserror::Error;

/// All errors that the iddrop protocol can raise.
#[derive(Debug, Error)]
pub enum IddropError {
    /// The claim's `receiver_pubkey` does not match the local identity.
    #[error("receiver mismatch: claim addressed to {expected_prefix}…")]
    ReceiverMismatch {
        /// First 16 hex chars of the expected receiver pubkey.
        expected_prefix: String,
    },

    /// The `nonce` in the claim does not match a known outstanding request.
    #[error("nonce mismatch: claim carries a nonce we never issued")]
    NonceMismatch,

    /// The `request_id` is unknown locally (= no outstanding offer/request).
    #[error("request_id unknown: {0}")]
    RequestIdUnknown(String),

    /// The claim's `sender_pubkey` does not match what AINS resolves for
    /// the `claimed_aint`.
    #[error("sender pubkey does not match AINS record for {claimed_aint}")]
    SenderAinsMismatch {
        /// The AINS handle that was claimed.
        claimed_aint: String,
    },

    /// AINS resolution failed for the claimed identity.
    #[error("AINS resolution failed for {claimed_aint}: {reason}")]
    AinsResolutionFailed {
        /// The AINS handle that could not be resolved.
        claimed_aint: String,
        /// Human-readable reason from the resolver.
        reason: String,
    },

    /// The claim is outside its valid time window (expired or not yet valid).
    #[error("time-window violation: now={now} window=[{issued_at}, {expires_at}]")]
    TimeWindow {
        /// Unix-seconds at the moment of validation.
        now: u64,
        /// Unix-seconds when the claim became valid.
        issued_at: u64,
        /// Unix-seconds when the claim expires.
        expires_at: u64,
    },

    /// Underlying TBZ envelope error.
    #[error("TBZ envelope error: {0}")]
    Envelope(String),

    /// Underlying transport error (proximity or wire).
    #[error("transport error: {0}")]
    Transport(String),

    /// JSON serialization or parse error.
    #[error("serialization error: {0}")]
    Serde(#[from] serde_json::Error),

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

    /// Catch-all for unexpected configuration or logic mistakes.
    #[error("internal error: {0}")]
    Internal(String),
}

/// Result type alias for iddrop operations.
pub type Result<T> = std::result::Result<T, IddropError>;
