use crate::pgp;

/// Result specialization.
pub type Result<T> = std::result::Result<T, Error>;

/// OpenPGP-Cert-D errors.
///
/// Errors defined by the [Shared PGP Certificate Directory].
///
///   [Shared PGP Certificate Directory]: https://sequoia-pgp.gitlab.io/pgp-cert-d/#section-6
#[derive(thiserror::Error, Debug)]
pub enum Error {
    /// The name was neither a valid fingerprint, nor a known special name.
    #[error("The name is not a valid fingerprint or a known special name")]
    BadName,
    /// The base directory cannot possibly contain a store.
    #[error("Base directory is not a store")]
    NotAStore,
    /// Error computing the fingerprint.
    ///
    /// This means that the certificate data was malformed
    /// (e.g. because it was ASCII-Armored), or the certificate's
    /// OpenPGP version was not supported by this crate.
    #[error("The data was not valid OpenPGP cert or key in binary format")]
    BadData(#[from] pgp::Error),

    /// Unsupported platform.
    #[error("Functionality is not supported on this platform: {0}")]
    UnsupportedPlatform(String),

    /// An IO error occurred.
    #[error("IO error")]
    IoError(#[from] std::io::Error),
    /// Any other error.
    ///
    /// This is used to return arbitrary errors from
    /// [`crate::CertD::insert`], [`crate::CertD::try_insert`],
    /// [`crate::CertD::insert_special`], and
    /// [`crate::CertD::try_insert_special`].
    #[error(transparent)]
    Other(#[from] Box<dyn std::error::Error + Send + Sync>),
}

impl From<walkdir::Error> for Error {
    fn from(error: walkdir::Error) -> Self {
        Self::Other(std::io::Error::from(error).into())
    }
}

impl From<anyhow::Error> for Error {
    fn from(error: anyhow::Error) -> Self {
        Self::Other(<Box<dyn std::error::Error + Send + Sync + 'static>>::from(
            error,
        ))
    }
}

#[derive(thiserror::Error, Debug)]
pub(crate) enum InternalError {
    /// The path does not represent a fingerprnt.
    #[error("The path does not represent a fingerprint")]
    BadFingerprintPath,
    /// The path is not inside the store directory.
    #[error("The path is not in the store")]
    PathNotInStore,
}
