/*
 * Copyright (c) 2022, able <abl3theabove@gmail.com>
 *
 * SPDX-License-Identifier: MPL-2.0
 */

pub mod drivers;
pub mod gdt;
pub mod init;
pub mod interrupts;
pub mod memory;

use limine::*;
use x86_64::{instructions::hlt, VirtAddr};

use crate::serial_println;

use self::drivers::allocator;

static HHDM: LimineHhdmRequest = LimineHhdmRequest::new(0);
static MMAP: LimineMmapRequest = LimineMmapRequest::new(0);

#[no_mangle]
pub fn x86_64_start() -> ! {
    let hhdm = HHDM.get_response().get().unwrap();
    let mmap = MMAP.get_response().get().unwrap();
    let phys_mem_offset = VirtAddr::new(hhdm.offset);

    let mut mapper = unsafe { memory::init(phys_mem_offset) };
    let mut frame_allocator = unsafe { memory::BootInfoFrameAllocator::init(mmap) };

    allocator::init_heap(&mut mapper, &mut frame_allocator).expect("heap initialization failed");

    crate::kmain::kernel_main(mapper, frame_allocator);
}

#[allow(unused)]
pub fn shutdown() -> ! {
    info!("Shutting down");
    unsafe {
        cpuio::outw(0x2000, 0x604);
    }

    sloop();
}

pub fn sloop() -> ! {
    loop {
        hlt();
    }
}

// TODO: Split up into the randomness and the password generation
pub fn generate_process_pass() -> u128 {
    // TODO: Move this into entropy_pool module
    use rdrand::RdRand;
    let gen = RdRand::new().unwrap();

    (gen.try_next_u64().unwrap() as u128) << 64 | (gen.try_next_u64().unwrap() as u128)
}
