use crate::maskers;

/// A builder for creating reusable custom masking strategies.
///
/// # Examples
/// ```
/// use maskify::Masker;
///
/// let masker = Masker::new()
///     .keep_start(4)
///     .keep_end(4)
///     .mask_char('#');
///
/// assert_eq!(masker.apply("1234567890123456"), "1234########3456");
/// assert_eq!(masker.apply("ABCDEFGHIJKLMNOP"), "ABCD########MNOP");
/// ```
#[derive(Debug, Clone)]
pub struct Masker {
    start: usize,
    end: usize,
    ch: char,
}

impl Masker {
    /// Create a new Masker with default settings (mask everything with `*`).
    pub fn new() -> Self {
        Masker {
            start: 0,
            end: 0,
            ch: '*',
        }
    }

    /// Set how many characters to keep visible at the start.
    pub fn keep_start(mut self, n: usize) -> Self {
        self.start = n;
        self
    }

    /// Set how many characters to keep visible at the end.
    pub fn keep_end(mut self, n: usize) -> Self {
        self.end = n;
        self
    }

    /// Set the masking character (default: `*`).
    pub fn mask_char(mut self, c: char) -> Self {
        self.ch = c;
        self
    }

    /// Apply the masking strategy to a string.
    #[must_use]
    pub fn apply(&self, input: &str) -> String {
        maskers::mask_custom(input, self.start, self.end, self.ch)
    }
}

impl Default for Masker {
    fn default() -> Self {
        Self::new()
    }
}