use crate::logging::format::LogFormat;
use crate::logging::logger::json::JsonAppender;
use crate::logging::logger::metrics::MetricsAppender;
use crate::logging::logger::r#async::AsyncAppender;
use crate::logging::logger::rolling_file::RollingFileAppender;
use crate::logging::logger::stdout::StdoutAppender;
use crate::shutdown_hooks::ShutdownHooks;
use bytes::Bytes;
use conjure_error::Error;
use futures_sink::Sink;
use serde::Serialize;
use std::io;
use std::pin::Pin;
use witchcraft_metrics::MetricRegistry;
use witchcraft_server_config::install::InstallConfig;
pub mod r#async;
mod byte_buffer;
pub mod json;
pub mod metrics;
pub mod rolling_file;
pub mod stdout;
pub type Appender<T> = AsyncAppender<T>;
pub async fn appender<T>(
config: &InstallConfig,
metrics: &MetricRegistry,
hooks: &mut ShutdownHooks,
) -> Result<Appender<T>, Error>
where
T: Serialize + LogFormat + 'static + Send,
T::Reporter: 'static + Send,
{
let appender: Pin<Box<dyn Sink<Bytes, Error = io::Error> + Sync + Send>> = if config
.use_console_log()
{
Box::pin(StdoutAppender::new())
} else {
let appender =
RollingFileAppender::new(T::FILE_STEM, T::SIZE_LIMIT_GB, T::TIME_LIMIT_DAYS).await?;
Box::pin(appender)
};
let appender = JsonAppender::new(appender);
let appender = MetricsAppender::new(appender, metrics);
let appender = AsyncAppender::new(appender, metrics, hooks);
Ok(appender)
}