use crate::url::ParseError;
use fluffer::{GemBytes, async_trait};
use std::str::Utf8Error;
use thiserror::Error;

#[derive(Error, Debug)]
#[allow(dead_code)]
pub enum ServiceError {
    #[error("No manifest")]
    NoManifest,
    #[error("Cannot send manifest")]
    CannotSendManifest,
    #[error("No need to send manifest")]
    NotSendingManifest,
    #[error("Nostr database error")]
    NostrDbError,
    #[error("Invalid pubkey")]
    InvalidPublicKey,
    #[error("Invalid URL")]
    InvalidUrl,
    #[error("Invalid sha256 blossom hash")]
    InvalidSha256,
    #[error("Object not found")]
    ObjectNotFound,
    #[error("Fetch events failed")]
    FetchEventsFailure,
    #[error("Cannot fetch blob from any blossom server")]
    CannotFetchBlob,
    #[error("URL parse error: {0}")]
    UrlParseError(#[from] ParseError),
    #[error("UTF8 error: {0}")]
    Utf8(#[from] Utf8Error),
    #[error("App error: {0}")]
    FlufferAppError(#[from] fluffer::AppErr),
    #[error("Confique error: {0}")]
    ConfiqueError(#[from] confique::Error),
    #[error("Nostr client error: {0}")]
    NostrClientError(#[from] nostr_sdk::client::Error),
    #[error("Blossom client error: {0}")]
    BlossomError(#[from] nostr_blossom::error::Error),
    #[error("IO error: {0}")]
    IOError(#[from] std::io::Error),
    #[error("Strip prefix error: {0}")]
    StripPrefixError(#[from] std::path::StripPrefixError),
}

#[async_trait]
impl GemBytes for ServiceError {
    async fn gem_bytes(self) -> Vec<u8> {
        let status = 40;

        format!("{} {}\r\n", status, self).into_bytes()
    }
}
