Framework for embedding localizations into Rust types
mod editor;
mod progress;
mod prompt;

use icu_locale::Locale;
use indicatif::MultiProgress;
use l10n_embed::Localize;
use thiserror::Error;

pub use editor::Editor;
pub use progress::ProgressBar;
pub use prompt::{Confirm, Input, Password, Select};

enum InteractionContext {
    Terminal,
    NonInteractive,
}

#[derive(Debug, Error)]
pub enum InteractionError {
    #[error(transparent)]
    IO(std::io::Error),
}

impl From<std::io::Error> for InteractionError {
    fn from(value: std::io::Error) -> Self {
        InteractionError::IO(value)
    }
}

impl From<dialoguer::Error> for InteractionError {
    fn from(value: dialoguer::Error) -> Self {
        match value {
            dialoguer::Error::IO(error) => Self::IO(error),
        }
    }
}

pub struct InteractionEnvironment {
    context: InteractionContext,
    locale: Locale,
    progress_bars: MultiProgress,
}

impl InteractionEnvironment {
    #[must_use]
    pub fn new(locale: Locale, interactive: bool) -> Self {
        Self {
            context: match interactive {
                true => InteractionContext::Terminal,
                false => InteractionContext::NonInteractive,
            },
            locale,
            progress_bars: MultiProgress::new(),
        }
    }

    pub fn emit_message<L: Localize>(&self, message: L) -> Result<(), InteractionError> {
        self.progress_bars
            .println(message.localize_for(&self.locale))?;

        Ok(())
    }
}