use super::systeminfo::SystemMemory;
use crate::arch::drivers::sysinfo::master;
use core::fmt::Display;
use kernel::allocator::ALLOCATOR;
use versioning::Version;
use x86_64::instructions::interrupts::{disable, enable};

pub enum CpuType {
    RiscV(String),
    X86_64(String),
}
impl Display for CpuType {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                CpuType::RiscV(s) => s,
                CpuType::X86_64(s) => s,
            }
        )
    }
}

/// simple info you would want to know in a neofetch like program
pub struct KernelInfo {
    // os: String,
    // host: String,
    pub kernel_version: Version,
    pub cpu: CpuType,
    // gpu: String,
    pub memory: SystemMemory,
}

impl KernelInfo {
    pub fn get() -> KernelInfo {
        disable();
        let allocator = ALLOCATOR.lock();
        let total = allocator.size();
        let used = allocator.used();
        enable();

        let cpu = CpuType::X86_64(master().unwrap().brand_string().unwrap().to_string());
        KernelInfo {
            kernel_version: Version {
                major: 0,
                minor: 0,
                patch: 0,
            },
            cpu,
            memory: SystemMemory { total, used },
        }
    }
}

impl Display for KernelInfo {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(
            f,
            "
            OS: AbleOS
            Host: {{}}
            Kernel: {}.{}.{}
            CPU: {}
            Memory: {}/{}
        ",
            self.kernel_version.major,
            self.kernel_version.minor,
            self.kernel_version.patch,
            self.cpu,
            self.memory.used,
            self.memory.total
        )
    }
}
