mod ansi;
mod error_output;
mod html;
mod html_template;
mod json;
mod markdown;
pub mod path;
mod progress;
mod sarif;
mod stats;
pub mod svg;
mod text;
mod trend_formatting;

pub use error_output::{
    print_error, print_error_full, print_info, print_info_full, print_warning, print_warning_full,
};
pub use html::HtmlFormatter;
pub use json::JsonFormatter;
pub use markdown::MarkdownFormatter;
pub use path::display_path;
pub use progress::ScanProgress;
pub use sarif::SarifFormatter;
pub use stats::{
    DirectoryStats, FileSortOrder, FileStatistics, LanguageStats, ProjectStatistics,
    StatsFormatter, StatsHtmlFormatter, StatsJsonFormatter, StatsMarkdownFormatter,
    StatsOutputMode, StatsTextFormatter,
};
pub use text::{ColorMode, TextFormatter};

use crate::checker::CheckResult;
use crate::error::Result;

/// Trait for formatting check results into various output formats.
pub trait OutputFormatter {
    /// Format the check results into a string.
    ///
    /// # Errors
    /// Returns an error if the formatting fails.
    fn format(&self, results: &[CheckResult]) -> Result<String>;
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum OutputFormat {
    #[default]
    Text,
    Json,
    Sarif,
    Markdown,
    Html,
}

impl std::str::FromStr for OutputFormat {
    type Err = String;

    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
        match s.to_lowercase().as_str() {
            "text" => Ok(Self::Text),
            "json" => Ok(Self::Json),
            "sarif" => Ok(Self::Sarif),
            "markdown" | "md" => Ok(Self::Markdown),
            "html" => Ok(Self::Html),
            _ => Err(format!("Unknown output format: {s}")),
        }
    }
}

#[cfg(test)]
#[path = "mod_tests.rs"]
mod tests;
