use crate::ExternalBlockNumber;

pub enum WeavingError<NetworkId> {
    DeadlineReached,
    NoStoredNetworks,
    UnparsableRequestBody,
    UnknownWeavingPhase(NetworkId),
    OffchainLockPeriod(NetworkId),
    NoEndpointsAvailable(NetworkId),
    ContradictoryHashes(NetworkId),
    ContradictoryBlocks(u32, ExternalBlockNumber, NetworkId),
}

impl<NetworkId: core::fmt::Debug> core::fmt::Debug for WeavingError<NetworkId> {
    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
        match self {
            Self::NoStoredNetworks => write!(fmt, "No stored networks to be watch on."),
            Self::UnparsableRequestBody => {
                write!(fmt, "HTTP request body contains invalid UTF-8 sequences.")
            }
            Self::DeadlineReached => {
                write!(fmt, "The request deadline or network timeout was hit.")
            }
            Self::UnknownWeavingPhase(network_id) => {
                write!(fmt, "Unknown weaving phase for network: {:?}.", network_id)
            }
            Self::OffchainLockPeriod(network_id) => write!(
                fmt,
                "Storage lock is still held for network: {:?}.",
                network_id
            ),
            Self::NoEndpointsAvailable(network_id) => write!(
                fmt,
                "Zero RPC URLs configured for network: {:?}.",
                network_id
            ),
            Self::ContradictoryHashes(network_id) => write!(
                fmt,
                "Divergence among reported hashes for network: {:?}.",
                network_id
            ),
            Self::ContradictoryBlocks(len, deviation, network_id) => {
                write!(fmt, "Divergence among {len} reported blocks exceeds the maximum threshold of {deviation} provided for network: {:?}.", network_id)
            }
        }
    }
}

pub enum RpcResolverError {
    JsonDeserializationFailed,
    UnparsableResponseBody,
    RpcEmptyResultField,
    UnknownNetworkType,
    InvalidResponseId,
    RpcProtocolError,
    DeadlineReached,
    Non200HttpCode,
    IoError,
    Unknown,
}

impl core::fmt::Debug for RpcResolverError {
    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
        match self {
            Self::JsonDeserializationFailed => {
                write!(fmt, "Failed to deserialize JSON payload into target type.")
            }
            Self::UnparsableResponseBody => {
                write!(fmt, "HTTP response body contains invalid UTF-8 sequences.")
            }
            Self::RpcEmptyResultField => write!(
                fmt,
                "The 'result' field in the JSON-RPC response is missing or null."
            ),
            Self::UnknownNetworkType => {
                write!(fmt, "he provided network type identifier is not supported.")
            }
            Self::RpcProtocolError => write!(
                fmt,
                "The server returned a protocol-level JSON-RPC error block."
            ),
            Self::IoError => write!(
                fmt,
                "An internal input/output or stream processing error occurred."
            ),
            Self::Non200HttpCode => {
                write!(fmt, "Server responded with a non-200 OK HTTP status code.")
            }
            Self::DeadlineReached => {
                write!(fmt, "The request deadline or network timeout was hit.")
            }
            Self::InvalidResponseId => write!(fmt, "Response ID does not match request ID."),
            Self::Unknown => write!(fmt, "An unclassified or generic error occurred."),
        }
    }
}
