// SPDX-FileCopyrightText: Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Module for handling physical and virtual memory regions
//!
//! A region is a continuous memory area in the given memory space.

use alloc::vec::Vec;
use log::debug;

use super::{
    address::{PhysicalAddress, VirtualAddress},
    page_pool::{PagePool, Pages},
    region_pool::Region,
};

/// Physical region
///
/// A physical memory region can be in three different state
/// * Unused
/// * Points to a page pool allocated address
/// * Points to a physical address without allocation
pub enum PhysicalRegion {
    Unused,
    Allocated(PagePool, Pages),
    PhysicalAddress(PhysicalAddress),
}

impl PhysicalRegion {
    /// Get physical memory address
    fn get_pa(&self) -> PhysicalAddress {
        match self {
            PhysicalRegion::Unused => panic!("Unused area has no PA"),
            PhysicalRegion::Allocated(_page_pool, pages) => pages.get_pa(),
            PhysicalRegion::PhysicalAddress(pa) => *pa,
        }
    }
}

/// Virtual region
///
/// A virtual memory region has a virtual address, a length and a physical region.
pub struct VirtualRegion {
    va: VirtualAddress,
    length: usize,
    physical_region: PhysicalRegion,
}

impl VirtualRegion {
    /// Create new virtual memory region without a physical region
    pub fn new(va: VirtualAddress, length: usize) -> Self {
        Self::new_from_fields(va, length, PhysicalRegion::Unused)
    }

    /// Create virtual region with points to a given physical address
    pub fn new_with_pa(pa: PhysicalAddress, va: VirtualAddress, length: usize) -> Self {
        Self::new_from_fields(va, length, PhysicalRegion::PhysicalAddress(pa))
    }

    /// Create virtual region by defining all the fields of the object
    fn new_from_fields(va: VirtualAddress, length: usize, physical_region: PhysicalRegion) -> Self {
        Self {
            va,
            length,
            physical_region,
        }
    }

    /// Get the base address of the linked physical region
    pub fn get_pa(&self) -> PhysicalAddress {
        self.physical_region.get_pa()
    }

    /// Get physical address for a virtual address
    pub fn get_pa_for_va(&self, va: VirtualAddress) -> PhysicalAddress {
        let offset = va.diff(self.va).unwrap();

        assert!(offset < self.length);
        self.get_pa().add_offset(offset).unwrap()
    }
}

impl Region for VirtualRegion {
    type Resource = PhysicalRegion;
    type Base = VirtualAddress;
    type Length = usize;
    type Alignment = usize;

    fn base(&self) -> Self::Base {
        self.va
    }

    fn length(&self) -> Self::Length {
        self.length
    }

    fn used(&self) -> bool {
        !matches!(self.physical_region, PhysicalRegion::Unused)
    }

    fn contains(&self, base: Self::Base, length: Self::Length) -> bool {
        if let (Some(end), Some(self_end)) =
            (base.add_offset(length), self.va.add_offset(self.length))
        {
            self.va <= base && end <= self_end
        } else {
            false
        }
    }

    fn try_alloc_aligned(
        &self,
        length: Self::Length,
        alignment: Self::Alignment,
    ) -> Option<Self::Base> {
        let aligned_base = self.va.align_up(alignment);
        let base_offset = aligned_base.diff(self.va)?;

        let required_length = base_offset.checked_add(length)?;
        if required_length <= self.length {
            Some(aligned_base)
        } else {
            None
        }
    }

    fn try_append(&mut self, other: &Self) -> bool {
        if let (Some(self_end), Some(new_length)) = (
            self.va.add_offset(self.length),
            self.length.checked_add(other.length),
        ) {
            if self_end == other.va {
                // VA is consecutive
                match (&self.physical_region, &other.physical_region) {
                    (PhysicalRegion::Unused, PhysicalRegion::Unused) => {
                        // Unused range can be merged without further conditions
                        self.length = new_length;
                        return true;
                    }
                    (
                        PhysicalRegion::PhysicalAddress(self_pa),
                        PhysicalRegion::PhysicalAddress(other_pa),
                    ) => {
                        // Used ranges can be only merged if the PA doesn't overflow and it is
                        // consecutive
                        if let Some(self_end_pa) = self_pa.add_offset(self.length) {
                            if self_end_pa == *other_pa {
                                self.length = new_length;
                                return true;
                            }
                        }
                    }

                    // PhyisicalRegion::Allocated instances cannot be merged at the moment. Not sure
                    // if it's a valid use case. If needed the pages has to be merged which might
                    // require tricks to invalidate the pages of 'other'.
                    _ => {}
                }
            }
        }

        false
    }

    fn create_split(
        &self,
        base: Self::Base,
        length: Self::Length,
        resource: Option<Self::Resource>,
    ) -> (Self, Vec<Self>) {
        assert!(self.contains(base, length));
        assert!(self.used() != resource.is_some());

        if let Some(physical_region) = resource {
            // Self is unused, setting part of it to used
            let pa = physical_region.get_pa();

            let mut res = Vec::new();
            if self.va != base {
                res.push(Self::new(self.va, base.diff(self.va).unwrap()));
            }

            res.push(Self::new_from_fields(base, length, physical_region));

            let end = base.add_offset(length).unwrap();
            let self_end = self.va.add_offset(self.length).unwrap();
            if end != self_end {
                res.push(Self::new(end, self_end.diff(end).unwrap()));
            }

            (
                Self::new_from_fields(base, length, PhysicalRegion::PhysicalAddress(pa)),
                res,
            )
        } else {
            // Self is used, mark part of it unused
            let mut res = Vec::new();
            if self.va != base {
                let physical_region = match &self.physical_region {
                    PhysicalRegion::Allocated(_page_pool, _pages) => {
                        todo!("Implement Pages::split");
                    }
                    PhysicalRegion::PhysicalAddress(pa) => PhysicalRegion::PhysicalAddress(*pa),
                    _ => {
                        panic!("Splitting unused region by other unused")
                    }
                };

                res.push(Self::new_from_fields(
                    self.va,
                    base.diff(self.va).unwrap(),
                    physical_region,
                ));
            }

            res.push(Self::new(base, length));

            let end = base.add_offset(length).unwrap();
            let self_end = self.va.add_offset(self.length).unwrap();
            if end != self_end {
                let physical_region = match &self.physical_region {
                    PhysicalRegion::Allocated(_page_pool, _pages) => {
                        todo!("Implement Pages::split");
                    }
                    PhysicalRegion::PhysicalAddress(pa) => {
                        let offset = end.diff(self.va).unwrap();
                        PhysicalRegion::PhysicalAddress(pa.add_offset(offset).unwrap())
                    }
                    _ => {
                        panic!("Splitting unused region by other unused")
                    }
                };

                res.push(Self::new_from_fields(
                    end,
                    self_end.diff(end).unwrap(),
                    physical_region,
                ));
            }

            (Self::new(base, length), res)
        }
    }
}

impl Drop for VirtualRegion {
    /// If the virtual region has a linked physical region which was allocated then release the
    /// allocated pages.
    fn drop(&mut self) {
        let mut physical_region = PhysicalRegion::Unused;

        core::mem::swap(&mut self.physical_region, &mut physical_region);

        if let PhysicalRegion::Allocated(page_pool, pages) = physical_region {
            debug!(
                "Dropping physical region with pages: PA={:#08x} VA={:#08x}",
                pages.get_pa().0,
                self.base().0,
            );

            page_pool.release_pages(pages).unwrap();
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{page_pool::PagePoolArea, KernelAddressTranslator};

    struct DummyKernelAddressTranslator {}

    impl KernelAddressTranslator for DummyKernelAddressTranslator {
        fn kernel_to_pa(va: VirtualAddress) -> PhysicalAddress {
            va.identity_pa()
        }

        fn pa_to_kernel(pa: PhysicalAddress) -> VirtualAddress {
            pa.identity_va()
        }
    }

    #[test]
    #[should_panic]
    fn test_physical_region_unused() {
        let region = PhysicalRegion::Unused;
        region.get_pa();
    }

    #[test]
    fn test_physical_region() {
        const PA: PhysicalAddress = PhysicalAddress(0x0123_4567_89ab_cdef);
        const LENGTH: usize = 0x8000_0000_0000;

        static PAGE_POOL_AREA: PagePoolArea<16> = PagePoolArea::new();
        let region = PhysicalRegion::Allocated(
            PagePool::new::<DummyKernelAddressTranslator, 16>(&PAGE_POOL_AREA),
            Pages::new(PA.0, LENGTH, true),
        );
        assert_eq!(PA, region.get_pa());

        let region = PhysicalRegion::PhysicalAddress(PA);
        assert_eq!(PA, region.get_pa());
    }

    #[test]
    fn test_virtual_region() {
        const VA: VirtualAddress = VirtualAddress(0x0123_4567_89ab_cdef);
        const PA: PhysicalAddress = PhysicalAddress(0xfedc_ba98_7654_3210);
        const LENGTH: usize = 0x8000_0000_0000;

        let region = VirtualRegion::new(VA, LENGTH);
        assert_eq!(VA, region.va);
        assert_eq!(VA, region.base());
        assert_eq!(LENGTH, region.length);
        assert_eq!(LENGTH, region.length());
        assert!(matches!(region.physical_region, PhysicalRegion::Unused));
        assert!(!region.used());

        let region = VirtualRegion::new_with_pa(PA, VA, LENGTH);
        assert_eq!(VA, region.va);
        assert_eq!(VA, region.base());
        assert_eq!(LENGTH, region.length);
        assert_eq!(LENGTH, region.length());
        assert!(matches!(
            region.physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));
        assert_eq!(PA, region.get_pa());
        assert!(region.used());
    }

    #[test]
    fn test_virtual_region_get_pa_for_va() {
        let region = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_0000_0000_0000),
            VirtualAddress(0x4000_0000_0000_0000),
            0x1000,
        );
        assert_eq!(
            PhysicalAddress(0x8000_0000_0000_0000),
            region.get_pa_for_va(VirtualAddress(0x4000_0000_0000_0000))
        );
        assert_eq!(
            PhysicalAddress(0x8000_0000_0000_0001),
            region.get_pa_for_va(VirtualAddress(0x4000_0000_0000_0001))
        );
        assert_eq!(
            PhysicalAddress(0x8000_0000_0000_0fff),
            region.get_pa_for_va(VirtualAddress(0x4000_0000_0000_0fff))
        );
    }

    #[test]
    #[should_panic]
    fn test_virtual_region_get_pa_for_va_low_va() {
        let region = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_0000_0000_0000),
            VirtualAddress(0x4000_0000_0000_0000),
            0x1000,
        );
        region.get_pa_for_va(VirtualAddress(0x3fff_ffff_ffff_ffff));
    }

    #[test]
    #[should_panic]
    fn test_virtual_region_get_pa_for_va_high_va() {
        let region = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_0000_0000_0000),
            VirtualAddress(0x4000_0000_0000_0000),
            0x1000,
        );
        region.get_pa_for_va(VirtualAddress(0x4000_0000_0000_1000));
    }

    #[test]
    fn test_virtual_region_try_alloc() {
        let region = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_1000),
            VirtualAddress(0x4000_1000),
            0x10000,
        );

        assert_eq!(
            Some(VirtualAddress(0x4000_1000)),
            region.try_alloc(0x1000, None)
        );
        assert_eq!(
            Some(VirtualAddress(0x4000_2000)),
            region.try_alloc(0x1000, Some(0x2000))
        );
        assert_eq!(None, region.try_alloc(0x1000, Some(0x10_0000)));
    }

    #[test]
    fn test_virtual_region_contains() {
        const VA: usize = 0x8000_0000_0000_0000;
        const LENGTH: usize = 0x8000_0000_0000;

        let region_overflow_end =
            VirtualRegion::new(VirtualAddress(0x8000_0000_0000_0000), 0x8000_0000_0000_0000);
        assert!(!region_overflow_end.contains(VirtualAddress(0x8000_0000_0000_0000), 1));

        let region =
            VirtualRegion::new(VirtualAddress(0x4000_0000_0000_0000), 0x8000_0000_0000_0000);
        assert!(!region.contains(VirtualAddress(0x8000_0000_0000_0000), 0x8000_0000_0000_0000));

        assert!(!region.contains(VirtualAddress(0x4000_0000_0000_0000), 0x8000_0000_0000_0001));
        assert!(!region.contains(VirtualAddress(0x3fff_ffff_ffff_ffff), 0x8000_0000_0000_0000));
        assert!(region.contains(VirtualAddress(0x4000_0000_0000_0000), 0x8000_0000_0000_0000));
        assert!(region.contains(VirtualAddress(0x4000_0000_0000_0000), 0x7fff_ffff_ffff_ffff));
        assert!(region.contains(VirtualAddress(0x4000_0000_0000_0001), 0x7fff_ffff_ffff_ffff));
    }

    #[test]
    fn test_virtual_region_try_append() {
        // Both unused
        let mut region_unused0 = VirtualRegion::new(VirtualAddress(0x4000_0000), 0x1000);
        let mut region_unused1 = VirtualRegion::new(VirtualAddress(0x4000_1000), 0x1000);

        assert!(!region_unused1.try_append(&region_unused0));
        assert_eq!(VirtualAddress(0x4000_0000), region_unused0.va);
        assert_eq!(0x1000, region_unused0.length);
        assert_eq!(VirtualAddress(0x4000_1000), region_unused1.va);
        assert_eq!(0x1000, region_unused1.length);

        assert!(region_unused0.try_append(&region_unused1));
        assert_eq!(VirtualAddress(0x4000_0000), region_unused0.va);
        assert_eq!(0x2000, region_unused0.length);
        assert_eq!(VirtualAddress(0x4000_1000), region_unused1.va);
        assert_eq!(0x1000, region_unused1.length);

        // Unused and PA region
        let mut region_unused = VirtualRegion::new(VirtualAddress(0x4000_0000), 0x1000);
        let region_physical = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_0000),
            VirtualAddress(0x4000_1000),
            0x1000,
        );
        assert!(!region_unused.try_append(&region_physical));
        assert_eq!(VirtualAddress(0x4000_0000), region_unused.va);
        assert_eq!(0x1000, region_unused.length);
        assert_eq!(VirtualAddress(0x4000_1000), region_physical.va);
        assert_eq!(0x1000, region_physical.length);

        // Both PA regions but non-consecutive PA ranges
        let mut region_physical0 = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_0000),
            VirtualAddress(0x4000_0000),
            0x1000,
        );
        let region_physical1 = VirtualRegion::new_with_pa(
            PhysicalAddress(0x9000_0000),
            VirtualAddress(0x4000_1000),
            0x1000,
        );
        assert!(!region_physical0.try_append(&region_physical1));
        assert_eq!(VirtualAddress(0x4000_0000), region_physical0.va);
        assert_eq!(0x1000, region_physical0.length);
        assert_eq!(VirtualAddress(0x4000_1000), region_physical1.va);
        assert_eq!(0x1000, region_physical1.length);

        // Both PA regions with consecutive PA ranges
        let mut region_physical0 = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_0000),
            VirtualAddress(0x4000_0000),
            0x1000,
        );
        let region_physical1 = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_1000),
            VirtualAddress(0x4000_1000),
            0x1000,
        );
        assert!(region_physical0.try_append(&region_physical1));
        assert_eq!(VirtualAddress(0x4000_0000), region_physical0.va);
        assert_eq!(0x2000, region_physical0.length);
        assert_eq!(VirtualAddress(0x4000_1000), region_physical1.va);
        assert_eq!(0x1000, region_physical1.length);

        // VA overflow
        let mut region_unused0: VirtualRegion =
            VirtualRegion::new(VirtualAddress(0x8000_0000_0000_0000), 0x8000_0000_0000_0000);
        let mut region_unused1 = VirtualRegion::new(VirtualAddress(0x4000_1000), 0x1000);

        assert!(!region_unused0.try_append(&region_unused1));
        assert_eq!(VirtualAddress(0x8000_0000_0000_0000), region_unused0.va);
        assert_eq!(0x8000_0000_0000_0000, region_unused0.length);
        assert_eq!(VirtualAddress(0x4000_1000), region_unused1.va);
        assert_eq!(0x1000, region_unused1.length);

        assert!(!region_unused1.try_append(&region_unused0));
        assert_eq!(VirtualAddress(0x8000_0000_0000_0000), region_unused0.va);
        assert_eq!(0x8000_0000_0000_0000, region_unused0.length);
        assert_eq!(VirtualAddress(0x4000_1000), region_unused1.va);
        assert_eq!(0x1000, region_unused1.length);

        // PA overflow
        let mut region_physical0 = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_0000_0000_0000),
            VirtualAddress(0x4000_0000),
            0x8000_0000_0000_0000,
        );
        let region_physical1 = VirtualRegion::new_with_pa(
            PhysicalAddress(0x9000_0000),
            VirtualAddress(0x8000_0000_4000_0000),
            0x1000,
        );
        assert!(!region_physical0.try_append(&region_physical1));
        assert_eq!(VirtualAddress(0x4000_0000), region_physical0.va);
        assert_eq!(0x8000_0000_0000_0000, region_physical0.length);
        assert_eq!(VirtualAddress(0x8000_0000_4000_0000), region_physical1.va);
        assert_eq!(0x1000, region_physical1.length);
    }

    #[test]
    fn test_virtual_region_create_split_by_used() {
        let region_unused = VirtualRegion::new(VirtualAddress(0x4000_0000), 0x4000);

        // New region at the start
        let (new_region, splitted_regions) = region_unused.create_split(
            VirtualAddress(0x4000_0000),
            0x1000,
            Some(PhysicalRegion::PhysicalAddress(PhysicalAddress(
                0x8000_0000,
            ))),
        );

        assert_eq!(VirtualAddress(0x4000_0000), new_region.va);
        assert_eq!(0x1000, new_region.length);
        assert_eq!(PhysicalAddress(0x8000_0000), new_region.get_pa());
        assert!(matches!(
            new_region.physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        assert_eq!(VirtualAddress(0x4000_0000), splitted_regions[0].va);
        assert_eq!(0x1000, splitted_regions[0].length);
        assert_eq!(PhysicalAddress(0x8000_0000), splitted_regions[0].get_pa());
        assert!(matches!(
            splitted_regions[0].physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        assert_eq!(VirtualAddress(0x4000_1000), splitted_regions[1].va);
        assert_eq!(0x3000, splitted_regions[1].length);
        assert!(matches!(
            splitted_regions[1].physical_region,
            PhysicalRegion::Unused
        ));

        // New region in the middle
        let (new_region, splitted_regions) = region_unused.create_split(
            VirtualAddress(0x4000_1000),
            0x1000,
            Some(PhysicalRegion::PhysicalAddress(PhysicalAddress(
                0x8000_0000,
            ))),
        );

        assert_eq!(VirtualAddress(0x4000_1000), new_region.va);
        assert_eq!(0x1000, new_region.length);
        assert_eq!(PhysicalAddress(0x8000_0000), new_region.get_pa());
        assert!(matches!(
            new_region.physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        assert_eq!(VirtualAddress(0x4000_0000), splitted_regions[0].va);
        assert_eq!(0x1000, splitted_regions[0].length);
        assert!(matches!(
            splitted_regions[0].physical_region,
            PhysicalRegion::Unused
        ));

        assert_eq!(VirtualAddress(0x4000_1000), splitted_regions[1].va);
        assert_eq!(0x1000, splitted_regions[1].length);
        assert_eq!(PhysicalAddress(0x8000_0000), splitted_regions[1].get_pa());
        assert!(matches!(
            splitted_regions[1].physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        assert_eq!(VirtualAddress(0x4000_2000), splitted_regions[2].va);
        assert_eq!(0x2000, splitted_regions[2].length);
        assert!(matches!(
            splitted_regions[2].physical_region,
            PhysicalRegion::Unused
        ));

        // New region at the end
        let (new_region, splitted_regions) = region_unused.create_split(
            VirtualAddress(0x4000_3000),
            0x1000,
            Some(PhysicalRegion::PhysicalAddress(PhysicalAddress(
                0x8000_0000,
            ))),
        );

        assert_eq!(VirtualAddress(0x4000_3000), new_region.va);
        assert_eq!(0x1000, new_region.length);
        assert_eq!(PhysicalAddress(0x8000_0000), new_region.get_pa());
        assert!(matches!(
            new_region.physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        assert_eq!(VirtualAddress(0x4000_0000), splitted_regions[0].va);
        assert_eq!(0x3000, splitted_regions[0].length);
        assert!(matches!(
            splitted_regions[0].physical_region,
            PhysicalRegion::Unused
        ));

        assert_eq!(VirtualAddress(0x4000_3000), splitted_regions[1].va);
        assert_eq!(0x1000, splitted_regions[1].length);
        assert_eq!(PhysicalAddress(0x8000_0000), splitted_regions[1].get_pa());
        assert!(matches!(
            splitted_regions[1].physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));
    }

    #[test]
    fn test_virtual_region_create_split_by_unused() {
        let region_unused = VirtualRegion::new_with_pa(
            PhysicalAddress(0x8000_0000),
            VirtualAddress(0x4000_0000),
            0x4000,
        );

        // New region at the start
        let (new_region, splitted_regions) =
            region_unused.create_split(VirtualAddress(0x4000_0000), 0x1000, None);

        assert_eq!(VirtualAddress(0x4000_0000), new_region.va); // TODO: why do we need explicit type here?
        assert_eq!(0x1000, new_region.length);
        assert!(matches!(new_region.physical_region, PhysicalRegion::Unused));

        assert_eq!(VirtualAddress(0x4000_0000), splitted_regions[0].va);
        assert_eq!(0x1000, splitted_regions[0].length);
        assert!(matches!(
            splitted_regions[0].physical_region,
            PhysicalRegion::Unused
        ));

        assert_eq!(VirtualAddress(0x4000_1000), splitted_regions[1].va);
        assert_eq!(0x3000, splitted_regions[1].length);
        assert_eq!(PhysicalAddress(0x8000_1000), splitted_regions[1].get_pa());
        assert!(matches!(
            splitted_regions[1].physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        // New region in the middle
        let (new_region, splitted_regions) =
            region_unused.create_split(VirtualAddress(0x4000_1000), 0x1000, None);

        assert_eq!(VirtualAddress(0x4000_1000), new_region.va);
        assert_eq!(0x1000, new_region.length);
        assert!(matches!(new_region.physical_region, PhysicalRegion::Unused));

        assert_eq!(VirtualAddress(0x4000_0000), splitted_regions[0].va);
        assert_eq!(0x1000, splitted_regions[0].length);
        assert_eq!(PhysicalAddress(0x8000_0000), splitted_regions[0].get_pa());
        assert!(matches!(
            splitted_regions[0].physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        assert_eq!(VirtualAddress(0x4000_1000), splitted_regions[1].va);
        assert_eq!(0x1000, splitted_regions[1].length);
        assert!(matches!(
            splitted_regions[1].physical_region,
            PhysicalRegion::Unused
        ));

        assert_eq!(VirtualAddress(0x4000_2000), splitted_regions[2].va);
        assert_eq!(0x2000, splitted_regions[2].length);
        assert_eq!(PhysicalAddress(0x8000_2000), splitted_regions[2].get_pa());
        assert!(matches!(
            splitted_regions[2].physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        // New region at the end
        let (new_region, splitted_regions) =
            region_unused.create_split(VirtualAddress(0x4000_3000), 0x1000, None);

        assert_eq!(VirtualAddress(0x4000_3000), new_region.va);
        assert_eq!(0x1000, new_region.length);
        assert!(matches!(new_region.physical_region, PhysicalRegion::Unused));

        assert_eq!(VirtualAddress(0x4000_0000), splitted_regions[0].va);
        assert_eq!(0x3000, splitted_regions[0].length);
        assert_eq!(PhysicalAddress(0x8000_0000), splitted_regions[0].get_pa());
        assert!(matches!(
            splitted_regions[0].physical_region,
            PhysicalRegion::PhysicalAddress(_)
        ));

        assert_eq!(VirtualAddress(0x4000_3000), splitted_regions[1].va);
        assert_eq!(0x1000, splitted_regions[1].length);

        assert!(matches!(
            splitted_regions[1].physical_region,
            PhysicalRegion::Unused
        ));
    }

    #[test]
    #[should_panic]
    fn test_virtual_region_does_not_contain() {
        let region = VirtualRegion::new(VirtualAddress(0x4000_0000), 0x1000);
        region.create_split(
            VirtualAddress(0x8000_0000),
            0x1000,
            Some(PhysicalRegion::PhysicalAddress(PhysicalAddress(
                0xc000_0000,
            ))),
        );
    }

    #[test]
    #[should_panic]
    fn test_virtual_region_create_split_same_used() {
        let region = VirtualRegion::new(VirtualAddress(0x4000_0000), 0x1000);
        region.create_split(
            VirtualAddress(0x4000_0000),
            0x1000,
            Some(PhysicalRegion::Unused),
        );
    }

    #[test]
    fn test_virtual_region_drop() {
        static PAGE_POOL_AREA: PagePoolArea<8192> = PagePoolArea::new();
        let page_pool = PagePool::new::<DummyKernelAddressTranslator, 8192>(&PAGE_POOL_AREA);
        let page = page_pool.allocate_pages(4096, None).unwrap();

        let physical_region = PhysicalRegion::Allocated(page_pool, page);

        // Testing physical region drop through virtualregion
        let virtual_region =
            VirtualRegion::new_from_fields(VirtualAddress(0x4000_0000), 1000, physical_region);
        drop(virtual_region);
    }
}
