#![allow(clippy::empty_loop)]

// use acpi::AcpiTables;
// use x86_64::instructions::interrupts::{disable, enable};

// use crate::{scratchpad, SCHEDULER, SCREEN_BUFFER};

use {
    crate::{
        arch::{init, sloop},

        relib::network::socket::{SimpleSock, Socket},
        // scheduler::SCHEDULER,
        // VgaBuffer,
        // SCREEN_BUFFER,
        scratchpad,
        // SCHEDULER,
        SCREEN_BUFFER,
    },
    facepalm::start_facepalm,
    lazy_static::lazy_static,
};

lazy_static! {
    // TODO: Change this structure to allow for multiple cores loaded
    pub static ref KERNEL_CONF: KernelConfig = KernelConfig::new();
}

/// The main entry point of the kernel
#[no_mangle]
pub fn kernel_main() -> ! {
    init::init();

    if KERNEL_CONF.logging.enabled {
        log::set_max_level(KERNEL_CONF.log_level());
    } else {
        log::set_max_level(log::LevelFilter::Off);
    }

    let mut scheduler = SCHEDULER.lock();
    /*





    use crate::scheduler::Priority::*;
    let mut process_1 = scheduler.new_process(High);
    process_1.capabilities.files = FileAccess::Some(vec![PathRep {
        location: FileLocations::Home,
        file_name: "test".to_string(),
    }]);
    scheduler.add_process(process_1);
    for ref_process in &scheduler.list {
        trace!("{:?}", ref_process);
    }
    drop(scheduler);



    */
    // use crate::proto_filetable::file::FileLocations;

    /*
            if false {
                let mut sock_print_id = SimpleSock::new();
                sock_print_id.register_protocol("Screen Printer".to_string());
                sock_print_id.write(format!("🐑").into());

                let mut mode = SCREEN_BUFFER.lock();

                mode.force_redraw();
                for current in (*String::from_utf8_lossy(&sock_print_id.peek().unwrap())).chars() {
                    // mode.draw_char(0, 0, current, from_vga_16(Color16::Red));
                }
                // mode.copy_to_buffer();
            }
    <<<<<<< HEAD
        */
    /*
        // TODO: create a scratchpad module
        if false {
            // Currently not implemented
            let acpi_handler = AcpiStruct {};
            let mut table;
            unsafe {
                table = AcpiTables::search_for_rsdp_bios(acpi_handler);
            }
        }

    =======
            mode.copy_to_buffer();
        }

        start_facepalm();
        scratchpad();
    >>>>>>> master

        */
    // start_facepalm();
    // scratchpad();

    /*
    if false {
        // disable();
        let mut mode = SCREEN_BUFFER.lock();
        mode.force_redraw();

        // mode.copy_to_buffer();
        mode.clear();

        mode.draw_char(0, 0, 'v', 0xff00ffff);

        // mode.copy_to_buffer();
        drop(mode);
        // enable()
        // sloop::halt();
    }


    */

    sloop()
}

pub fn cpu_socket_startup() {
    let mut cpu_info_socket = SimpleSock::new();
    cpu_info_socket.register_protocol("CPU_INFO".to_string());

    // let x = master().unwrap();
    // let _xyz = x.brand_string().unwrap();
}

pub fn log_version_data() {
    info!("{} v{:?}", RELEASE_TYPE, KERNEL_VERSION);
    info!(
        "Brand String: ",
        // master().unwrap().brand_string().unwrap()
    );
}

// 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();

    // TODO: Split off into process module
    // let ret = (gen.try_next_u64().unwrap() as u128) << 64 | (gen.try_next_u64().unwrap() as u128);
    // ret
    123
}
/*

// TODO: move to a better place
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AcpiStruct {}

impl acpi::AcpiHandler for AcpiStruct {
    unsafe fn map_physical_region<T>(
        &self,
        physical_address: usize,
        size: usize,
    ) -> acpi::PhysicalMapping<Self, T> {
        info!("PHYS ADDR: {:?}", physical_address);
        info!("Size: {:?}", size);

        todo!("map_physical_region");
    }

    fn unmap_physical_region<T>(_region: &acpi::PhysicalMapping<Self, T>) {
        todo!("unmap_physical_region");
    }
}
*/

use kernel::KERNEL_VERSION;

use crate::{boot_conf::KernelConfig, scheduler::SCHEDULER, systeminfo::RELEASE_TYPE};