use core::sync::atomic::Ordering;

use crate::kmain::{BOOT_CONF, TICK};
use crate::serial_println;
use lliw::{Fg, Reset};
pub use log::{debug, info, trace, warn};
use log::{Level, Metadata, Record};

use crate::arch::drivers::timer::TIMER_INTERRUPT_HERTZ;

struct SimpleLogger;

impl log::Log for SimpleLogger {
    fn enabled(&self, metadata: &Metadata) -> bool {
        metadata.level() <= Level::Trace
    }

    fn log(&self, record: &Record) {
        if self.enabled(record.metadata()) {
            let color;
            let time = TICK.load(Ordering::Relaxed) as f64;

            let time_float = time / TIMER_INTERRUPT_HERTZ;

            match record.level() {
                log::Level::Error => color = (Fg::Red, "$RED$"),
                log::Level::Warn => color = (Fg::LightYellow, "$LIGHTYELLOW$"),
                log::Level::Info => color = (Fg::LightWhite, "$LIGHTGRAY$"),
                log::Level::Debug => color = (Fg::Blue, "$BLUE$"),
                log::Level::Trace => color = (Fg::Yellow, "$YELLOW$"),
            }

            serial_println!(
                "[{}{}{}][{}{}{}] {}",
                color.0,
                record.level(),
                Fg::Reset,
                Fg::Green,
                time_float,
                Reset,
                record.args(),
            );
        }
    }

    fn flush(&self) {}
}

use log::{LevelFilter, SetLoggerError};

static LOGGER: SimpleLogger = SimpleLogger;

pub fn init() -> Result<(), SetLoggerError> {
    log::set_logger(&LOGGER).map(|()| log::set_max_level(LevelFilter::Trace))
}
