use tracing::level_filters::LevelFilter;
use tracing_appender::non_blocking::{NonBlockingBuilder, WorkerGuard};
use tracing_subscriber::{
    EnvFilter,
    fmt::{self, fmt},
};

/// Writes to stdout with a default level of "info" that can
/// be changed with the `RUST_LOG` environment variable.
///
/// Uses a test writer and "debug" level if running unit/integration tests.
pub fn init_logger(blocking: bool) -> Option<WorkerGuard> {
    let is_test = cfg!(any(test, feature = "integration"));
    let level = if is_test {
        LevelFilter::DEBUG
    } else {
        LevelFilter::INFO
    };
    let filter = EnvFilter::builder()
        .with_default_directive(level.into())
        .from_env_lossy();
    let format = fmt::format()
        .without_time()
        .with_ansi(false)
        .with_target(false)
        .compact();

    let logger = fmt().event_format(format).with_env_filter(filter);

    if is_test {
        let _ = logger.with_test_writer().try_init();
    } else {
        if blocking {
            let _ = logger.with_writer(std::io::stdout).try_init();
        } else {
            let (non_blocking, guard) = NonBlockingBuilder::default()
                .lossy(true) // while dropping logs isn't great, the alternative is dropping requests
                .buffered_lines_limit(200_000)
                .finish(std::io::stdout());
            let _ = logger.with_writer(non_blocking).try_init();
            return Some(guard);
        }
    }

    None
}
