// SPDX-License-Identifier: GPL-2.0

//! Memory layout.
//!
//! Custom layout types extending or improving [`Layout`].

use core::{alloc::Layout, marker::PhantomData};

/// Error when constructing an [`ArrayLayout`].
pub struct LayoutError;

/// A layout for an array `[T; n]`.
///
/// # Invariants
///
/// - `len * size_of::<T>() <= isize::MAX`.
pub struct ArrayLayout<T> {
    len: usize,
    _phantom: PhantomData<fn() -> T>,
}

impl<T> Clone for ArrayLayout<T> {
    fn clone(&self) -> Self {
        *self
    }
}
impl<T> Copy for ArrayLayout<T> {}

const ISIZE_MAX: usize = isize::MAX as usize;

impl<T> ArrayLayout<T> {
    /// Creates a new layout for `[T; 0]`.
    pub const fn empty() -> Self {
        // INVARIANT: `0 * size_of::<T>() <= isize::MAX`.
        Self {
            len: 0,
            _phantom: PhantomData,
        }
    }

    /// Creates a new layout for `[T; len]`.
    ///
    /// # Errors
    ///
    /// When `len * size_of::<T>()` overflows or when `len * size_of::<T>() > isize::MAX`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use kernel::alloc::layout::{ArrayLayout, LayoutError};
    /// let layout = ArrayLayout::<i32>::new(15)?;
    /// assert_eq!(layout.len(), 15);
    ///
    /// // Errors because `len * size_of::<T>()` overflows.
    /// let layout = ArrayLayout::<i32>::new(isize::MAX as usize);
    /// assert!(layout.is_err());
    ///
    /// // Errors because `len * size_of::<i32>() > isize::MAX`,
    /// // even though `len < isize::MAX`.
    /// let layout = ArrayLayout::<i32>::new(isize::MAX as usize / 2);
    /// assert!(layout.is_err());
    ///
    /// # Ok::<(), Error>(())
    /// ```
    pub const fn new(len: usize) -> Result<Self, LayoutError> {
        match len.checked_mul(core::mem::size_of::<T>()) {
            Some(size) if size <= ISIZE_MAX => {
                // INVARIANT: We checked above that `len * size_of::<T>() <= isize::MAX`.
                Ok(Self {
                    len,
                    _phantom: PhantomData,
                })
            }
            _ => Err(LayoutError),
        }
    }

    /// Creates a new layout for `[T; len]`.
    ///
    /// # Safety
    ///
    /// `len` must be a value, for which `len * size_of::<T>() <= isize::MAX` is true.
    pub unsafe fn new_unchecked(len: usize) -> Self {
        // INVARIANT: By the safety requirements of this function
        // `len * size_of::<T>() <= isize::MAX`.
        Self {
            len,
            _phantom: PhantomData,
        }
    }

    /// Returns the number of array elements represented by this layout.
    pub const fn len(&self) -> usize {
        self.len
    }

    /// Returns `true` when no array elements are represented by this layout.
    pub const fn is_empty(&self) -> bool {
        self.len == 0
    }
}

impl<T> From<ArrayLayout<T>> for Layout {
    fn from(value: ArrayLayout<T>) -> Self {
        let res = Layout::array::<T>(value.len);
        // SAFETY: By the type invariant of `ArrayLayout` we have
        // `len * size_of::<T>() <= isize::MAX` and thus the result must be `Ok`.
        unsafe { res.unwrap_unchecked() }
    }
}
