use core::str::FromStr;

use crate::debug::LogLevel;

use super::SetOption;

/// Debugging/logging-related options
#[derive(Debug)]
pub struct DebugOptions {
    /// Default log level used for serial devices
    pub serial_level: LogLevel,
    /// Default log level used for proper display devices
    pub display_level: LogLevel,
    /// If set, logs produced by the `debug_trace` syscall are ignored
    pub disable_program_trace: bool,
}

/// Device-tree related options
#[derive(Debug)]
pub struct DeviceTreeOptions {
    /// If set, logs missing drivers for device tree nodes
    pub log_missing: bool,
}

impl Default for DebugOptions {
    fn default() -> Self {
        Self {
            serial_level: LogLevel::Info,
            display_level: LogLevel::Info,
            disable_program_trace: false,
        }
    }
}

impl SetOption for DebugOptions {
    fn set_key_value(&mut self, key: &str, value: &str) -> bool {
        match key {
            "serial-level" if let Ok(level) = LogLevel::from_str(value) => {
                self.serial_level = level;
                true
            }
            "display-level" if let Ok(level) = LogLevel::from_str(value) => {
                self.display_level = level;
                true
            }
            "log_level" if let Ok(level) = LogLevel::from_str(value) => {
                self.serial_level = level;
                self.display_level = level;
                true
            }
            _ => false,
        }
    }

    fn set_flag(&mut self, value: &str) -> bool {
        match value {
            "disable-program-trace" => {
                self.disable_program_trace = true;
                true
            }
            _ => false,
        }
    }
}

impl Default for DeviceTreeOptions {
    fn default() -> Self {
        Self { log_missing: true }
    }
}

impl SetOption for DeviceTreeOptions {
    fn set_key_value(&mut self, _key: &str, _value: &str) -> bool {
        false
    }

    fn set_flag(&mut self, value: &str) -> bool {
        match value {
            "log-missing" => {
                self.log_missing = true;
                true
            }
            _ => false,
        }
    }
}
