// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: MIT

#![allow(dead_code)]

use crate::{LOGGER, LogLevel, format, log_info, memory::HHDM_RESPONSE};
use x86_64::{
    PhysAddr, VirtAddr,
    registers::control::*,
    structures::paging::{PageTable, PageTableFlags},
};

pub fn get_mappings() {
    log_info!("Paging: {}", Cr0::read().contains(Cr0Flags::PAGING));
    log_info!(
        "Protection: {}",
        Cr0::read().contains(Cr0Flags::PROTECTED_MODE_ENABLE)
    );
    log_info!(
        "Physical Address Extensions: {}",
        x86_64::registers::control::Cr4::read().contains(Cr4Flags::PHYSICAL_ADDRESS_EXTENSION)
    );
    log_info!(
        "Page Size Extensions: {}",
        Cr4::read().contains(Cr4Flags::PAGE_SIZE_EXTENSION)
    );
    log_info!(
        "Paging mode: {}",
        match crate::memory::PAGING_REQUEST.get_response().unwrap().mode() {
            limine::paging::Mode::FOUR_LEVEL => "Four-Level",
            limine::paging::Mode::FIVE_LEVEL => "Five-Level",
            _ => unreachable!(),
        }
    );
    let pml4_phys_addr = Cr3::read_raw().0.start_address();
    log_info!("Page Map Level 4 Address: 0x{:x}", pml4_phys_addr.as_u64());
    log_info!(
        "Page-Level Write-Through: {}",
        Cr3::read().1.contains(Cr3Flags::PAGE_LEVEL_WRITETHROUGH)
    );
    log_info!(
        "Page-Level Cache Disable: {}",
        Cr3::read().1.contains(Cr3Flags::PAGE_LEVEL_CACHE_DISABLE)
    );
    let pml4: &'static mut PageTable = table_from_phys_addr(pml4_phys_addr);

    iter_table(pml4, 4);
}

fn table_from_phys_addr(address: PhysAddr) -> &'static mut PageTable {
    let virt_addr: VirtAddr = VirtAddr::new(address.as_u64() + HHDM_RESPONSE.offset());
    let ptr: *mut PageTable = virt_addr.as_mut_ptr();
    unsafe { &mut *ptr }
}

fn iter_table(table: &'static mut PageTable, level: usize) {
    if level == 1 {
        for page_entry in table.iter() {
            if page_entry.flags().contains(PageTableFlags::PRESENT) {
                log_info!(
                    "Page entry: 0x{:x}, flags: {:?}",
                    page_entry.addr(),
                    page_entry.flags()
                );
            }
        }
    } else {
        for table_entry in table.iter() {
            if table_entry.flags().contains(PageTableFlags::PRESENT) {
                log_info!(
                    "Table entry: 0x{:x}, flags: {:?}",
                    table_entry.addr(),
                    table_entry.flags()
                );
                iter_table(table_from_phys_addr(table_entry.addr()), level - 1);
            }
        }
    }
}
