use log::LevelFilter;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Debug, Deserialize)]
pub enum LogLevel {
    /// A level lower than all log levels.
    Off,
    /// Corresponds to the `Error` log level.
    Error,
    /// Corresponds to the `Warn` log level.
    Warn,
    /// Corresponds to the `Info` log level.
    Info,
    /// Corresponds to the `Debug` log level.
    Debug,
    /// Corresponds to the `Trace` log level.
    Trace,
}

#[derive(Serialize, Debug, Deserialize)]
pub struct KernelConfig {
    pub boot: BootConfig,
    pub logging: LoggingConfig,
    pub tests: TestsConfig,
}

impl KernelConfig {
    pub fn new() -> Self {
        toml::from_str(include_str!("../assets/kernel.toml")).unwrap()
    }

    pub fn log_level(&self) -> LevelFilter {
        use LevelFilter::*;
        match self.logging.level {
            LogLevel::Off => Off,
            LogLevel::Error => Error,
            LogLevel::Warn => Warn,
            LogLevel::Info => Info,
            LogLevel::Debug => Debug,
            LogLevel::Trace => Trace,
        }
    }
}

impl Default for KernelConfig {
    fn default() -> Self {
        Self::new()
    }
}

#[derive(Serialize, Debug, Deserialize)]
pub struct LoggingConfig {
    pub enabled: bool,
    pub log_to_serial: bool,
    pub level: LogLevel,
}
#[derive(Serialize, Debug, Deserialize)]
pub struct TestsConfig {
    pub run_tests: bool,
    pub run_demos: bool,
    pub run_shader_tests: bool,
}

#[derive(Serialize, Debug, Deserialize)]
pub struct BootConfig {
    pub system_processes: Vec<String>,
    pub user_processes: Vec<String>,
}
