//! Errors for this crate.

/// SOP errors.
///
/// These are the errors [defined] by the Stateless OpenPGP Protocol.
///
///   [defined]: https://www.ietf.org/archive/id/draft-dkg-openpgp-stateless-cli-08.html#name-failure-modes
#[derive(thiserror::Error, Debug)]
pub enum Error {
    /// Unspecified failure.
    #[error("Unspecified failure")]
    UnspecifiedFailure,

    /// No acceptable signatures found ("sop verify").
    #[error("No acceptable signatures found")]
    NoSignature,

    /// Asymmetric algorithm unsupported ("sop encrypt").
    #[error("Asymmetric algorithm unsupported")]
    UnsupportedAsymmetricAlgo,

    /// Certificate not encryption-capable (e.g., expired, revoked,
    /// unacceptable usage flags) ("sop encrypt").
    #[error("Certificate not encryption-capable")]
    CertCannotEncrypt,

    /// Key not signature-capable (e.g., expired, revoked,
    /// unacceptable usage flags) (`sop sign` and `sop encrypt` with
    /// `--sign-with`).
    #[error("Key not signing-capable")]
    KeyCannotSign,

    /// Missing required argument.
    #[error("Missing required argument")]
    MissingArg,

    /// Incomplete verification instructions ("sop decrypt").
    #[error("Incomplete verification instructions")]
    IncompleteVerification,

    /// Unable to decrypt ("sop decrypt").
    #[error("Unable to decrypt")]
    CannotDecrypt,

    /// Non-"UTF-8" or otherwise unreliable password ("sop encrypt").
    #[error("Non-UTF-8 or otherwise unreliable password")]
    PasswordNotHumanReadable,

    /// Unsupported option.
    #[error("Unsupported option")]
    UnsupportedOption,

    /// Invalid data type (no secret key where "KEY" expected, etc).
    #[error("Invalid data type")]
    BadData,

    /// Non-text input where text expected.
    #[error("Non-text input where text expected")]
    ExpectedText,

    /// Output file already exists.
    #[error("Output file already exists")]
    OutputExists,

    /// Input file does not exist.
    #[error("Input file does not exist")]
    MissingInput,

    /// A "KEY" input is protected (locked) with a password, and "sop" cannot
    /// unlock it with any of the --with-key-password options.
    #[error("A KEY input is protected with a password and unlocking failed")]
    KeyIsProtected,

    /// A indirect input parameter is a special designator (it starts with
    /// "@"), and a filename matching the designator is actually present.
    #[error("A indirect input parameter is a special designator matches file")]
    AmbiguousInput,

    /// Options were supplied that are incompatible with each other.
    #[error("Options were supplied that are incompatible with each other")]
    IncompatibleOptions,

    /// Operation not implemented.
    #[error("Operation not implemented")]
    NotImplemented,

    /// The requested profile is unsupported (sop generate-key, sop
    /// encrypt), or the indicated subcommand does not accept profiles
    /// (sop list-profiles).
    #[error("Profile not supported")]
    UnsupportedProfile,

    /// The primary key of a KEYS object is too weak or revoked.
    #[error("The primary key of a KEYS object is too weak or revoked")]
    PrimaryKeyBad,

    /// The CERTS object has no matching User ID.
    #[error("The CERTS object has no matching User ID")]
    CertUseridNoMatch,

    /// An IO error occurred.
    #[error(transparent)]
    IoError(#[from] std::io::Error),
}

/// Errors during parsing of SOP string representations.
///
/// For types with a defined string representation, we implement
/// [`std::str::FromStr`] for parsing.  This type is used to report
/// errors during parsing.
#[derive(thiserror::Error, Debug)]
#[error("Invalid argument: {}", _0)]
pub struct ParseError(pub String);
