use super::{FilterOption, FilterPlugin};
use std::io::{Read, Result, Write};
use strip_ansi_escapes::Writer;

/// A filter that removes ANSI escape sequences from the input.
///
/// # Fields
///
/// None, stateless filter.
#[derive(Default)]
pub struct StripAnsiFilter;

impl StripAnsiFilter {
    /// Creates a new `StripAnsiFilter`.
    ///
    /// # Returns
    ///
    /// A new instance of `StripAnsiFilter`.
    pub fn new() -> Self {
        Self
    }
}

impl FilterPlugin for StripAnsiFilter {
    /// Filters the input by stripping ANSI escape sequences and writing the plain text to the output.
    ///
    /// # Arguments
    ///
    /// * `reader` - Mutable reference to the input reader providing the data stream with potential ANSI codes.
    /// * `writer` - Mutable reference to the output writer where plain text is sent.
    ///
    /// # Returns
    ///
    /// Returns `Ok(())` on success, or an `io::Error` if reading or writing fails.
    fn filter(&mut self, reader: &mut dyn Read, writer: &mut dyn Write) -> Result<()> {
        let mut ansi_writer = Writer::new(writer);
        std::io::copy(reader, &mut ansi_writer)?;
        ansi_writer.flush()?;
        Ok(())
    }

    /// Clones this filter into a new boxed instance.
    ///
    /// # Returns
    ///
    /// A new `Box<dyn FilterPlugin>` representing a clone of this filter.
    fn clone_box(&self) -> Box<dyn FilterPlugin> {
        Box::new(Self)
    }

    /// Returns the configuration options for this filter (none required).
    ///
    /// # Returns
    ///
    /// An empty vector since this filter has no configurable options.
    fn options(&self) -> Vec<FilterOption> {
        Vec::new() // strip_ansi doesn't take any options
    }

    fn description(&self) -> &str {
        "Strip ANSI escape sequences"
    }
}
