//! All error types that are exposed by this crate.
use std::{path::PathBuf, string::FromUtf8Error};

use alpm_pkgbuild::error::Error as PkgbuildError;
use fluent_i18n::t;
use thiserror::Error;

use crate::pkgbuild_bridge::error::BridgeError;
#[cfg(doc)]
use crate::{SourceInfoV1, source_info::parser::SourceInfoContent};

/// The high-level error that can occur when using this crate.
///
/// Notably, it contains an important enum in the context of parsing:
/// - `ParseError` is an already formatted error generated by the `winnow` parser. This effectively
///   means that some invalid data has been encountered
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum Error {
    /// ALPM type error
    #[error("{msg}", msg = t!("error-alpm-type", { "error" => .0.to_string() }))]
    AlpmType(#[from] alpm_types::Error),

    /// IO error
    #[error("{msg}", msg = t!("error-io", { "context" => .context, "error" => .source.to_string() }))]
    Io {
        /// The context in which the IO error occurred.
        context: String,
        /// The underlying IO error.
        source: std::io::Error,
    },

    /// IO error with additional path info for more context.
    #[error("{msg}", msg = t!("error-io-path", {
        "path" => path,
        "context" => context,
        "error" => source.to_string()
    }))]
    IoPath {
        /// The path related to the IO error.
        path: PathBuf,
        /// The context in which the IO error occurred.
        context: String,
        /// The underlying IO error.
        source: std::io::Error,
    },

    /// UTF-8 parse error when reading the input file.
    #[error("{msg}", msg = t!("error-invalid-utf8", { "error" => .0.to_string() }))]
    InvalidUTF8(#[from] FromUtf8Error),

    /// A section or keyword is missing for a SRCINFO schema version.
    #[error("{msg}", msg = t!("error-missing-keyword", { "keyword" => keyword }))]
    MissingKeyword {
        /// The missing keyword.
        keyword: &'static str,
    },

    /// A parsing error that occurred during winnow file parsing.
    #[error("{msg}", msg = t!("error-parse", { "error" => .0 }))]
    ParseError(String),

    /// Unsupported schema version
    #[error("{msg}", msg = t!("error-unsupported-schema-version", { "version" => .0 }))]
    UnsupportedSchemaVersion(String),

    /// A alpm-pkgbuild bridge error that occurred when converting a PKGBUILD to a [`SourceInfoV1`].
    ///
    /// See [`PkgbuildError`] for further details.
    #[error("{msg}", msg = t!("error-bridge", { "error" => .0.to_string() }))]
    BridgeError(#[from] PkgbuildError),

    /// A logical error occurred when transforming `alpm-pkgbuild-bridge` script output to a
    /// [`SourceInfoV1`] struct.
    ///
    /// See [`BridgeError`] for further details.
    #[error("{msg}", msg = t!("error-bridge-conversion", { "error" => .0.to_string() }))]
    BridgeConversionError(#[from] BridgeError),
}
