use chrono::{Datelike, Local, Timelike};
use tracing::Level;
use tracing_subscriber::fmt::time::FormatTime;

pub fn init(level: Level) {
    tracing_subscriber::fmt()
        .with_line_number(true)
        .with_max_level(level)
        .with_timer(Timer)
        .init();
}

struct Timer;

impl FormatTime for Timer {
    fn format_time(&self, w: &mut tracing_subscriber::fmt::format::Writer<'_>) -> std::fmt::Result {
        let now = Local::now();
        write!(
            w,
            "{}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}",
            now.year(),
            now.month(),
            now.day(),
            now.hour(),
            now.minute(),
            now.second(),
            now.nanosecond() / 1000000
        )
    }
}

#[cfg(test)]
mod tests_trace {
    use super::*;
    use std::{thread, time::Duration};
    use tracing::debug;
    use tracing::info;
    use tracing::warn;

    #[test]
    fn test_format_time() {
        init("debug".parse::<Level>().unwrap());
        info!("info1");
        thread::sleep(Duration::from_secs(1));
        info!("info2");
        thread::sleep(Duration::from_secs(1));
        info!("info3");
        thread::sleep(Duration::from_millis(100));
        warn!("warn1");
        thread::sleep(Duration::from_millis(100));
        warn!("warn2");
        thread::sleep(Duration::from_millis(100));
        debug!("debug1");
    }
}
