use fdt::*;
use lazy_static::lazy_static;
use limine::{request::DeviceTreeBlobRequest, response::DeviceTreeBlobResponse};

use crate::{format, log::*, log_info, log_trace, log_warning};

#[used]
#[unsafe(link_section = ".requests")]
pub static DTB_REQUEST: DeviceTreeBlobRequest = limine::request::DeviceTreeBlobRequest::new();

lazy_static! {
    pub static ref DTB: Option<&'static DeviceTreeBlobResponse> = match DTB_REQUEST.get_response() {
        Some(resp) => {
            log_info!("Device: Got DTB pointer");
            Some(resp)
        }
        None => {
            log_warning!("Device: Did not get DTB pointer");
            None
        }
    };
}

#[allow(dead_code)]
pub fn device_tree_parsed() -> Option<Fdt<'static>> {
    if let Some(ok_dtb) = *DTB
        && let Ok(ok_parsed_dt) = unsafe { fdt::Fdt::from_ptr(ok_dtb.dtb_ptr() as *const u8) }
    {
        log_trace!("Device: Parsed device tree");
        Some(ok_parsed_dt)
    } else {
        None
    }
}
