use uefi::{
    prelude::BootServices,
    proto::media::file::{Directory, File, FileAttribute, FileInfo, FileMode, RegularFile},
    table::boot::{AllocateType, MemoryType},
    CStr16, Error,
};

fn do_load(file: &mut RegularFile, base: u64, size: u64) -> Result<(), Error> {
    let buffer = unsafe { core::slice::from_raw_parts_mut(base as *mut u8, size as usize) };
    file.read(buffer)?;
    Ok(())
}

pub fn load_somewhere(
    bs: &BootServices,
    root: &mut Directory,
    filename: &CStr16,
) -> Result<(u64, u64), Error> {
    const MAXIMUM_ADDRESS: u64 = 0x100000000;

    let mut info_buffer: [u8; 1024] = [0; 1024];

    let file = root.open(filename, FileMode::Read, FileAttribute::empty())?;
    let mut file = file.into_regular_file().unwrap();

    let file_info: &FileInfo = file.get_info(&mut info_buffer).unwrap();
    let size = file_info.file_size();
    let page_count = size.div_ceil(0x1000);

    let base = bs.allocate_pages(
        AllocateType::MaxAddress(MAXIMUM_ADDRESS),
        MemoryType::LOADER_DATA,
        page_count as _,
    )?;

    do_load(&mut file, base, size)?;

    Ok((base, size))
}
