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

//! Implementation of the FF-A Memory Management protocol.
//!
//! FF-A describes mechanisms and interfaces that enable FF-A components to manage access and
//! ownership of memory regions in the physical address space. FF-A components can use a combination
//! of Framework and Partition messages to manage memory regions in the following ways:
//! - The Owner of a memory region can transfer its ownership to another FF-A endpoint.
//! - The Owner of a memory region can transfer its access to one or more FF-A endpoints.
//! - The Owner of a memory region can share access to it with one or more FF-A endpoints.
//! - The Owner can reclaim access to a memory region after the FF-A endpoints that were granted
//!   access to that memory region have relinquished their access.

use crate::ffa_v1_1::{
    composite_memory_region_descriptor, constituent_memory_region_descriptor,
    endpoint_memory_access_descriptor, memory_access_permission_descriptor,
    memory_relinquish_descriptor, memory_transaction_descriptor,
};
use core::mem::size_of;
use thiserror::Error;
use zerocopy::{FromBytes, IntoBytes};

/// Rich error types returned by this module. Should be converted to [`crate::FfaError`] when used
/// with the `FFA_ERROR` interface.
#[derive(Debug, Error)]
pub enum Error {
    #[error("Invalid cacheability attribute {0}")]
    InvalidCacheability(u16),
    #[error("Invalid shareability attribute {0}")]
    InvalidShareability(u16),
    #[error("Invalid device memory attributes {0}")]
    InvalidDevMemAttributes(u16),
    #[error("Invalid instruction access permission {0}")]
    InvalidInstrAccessPerm(u8),
    #[error("Invalid instruction data permission {0}")]
    InvalidDataAccessPerm(u8),
    #[error("Invalid memory type {0}")]
    InvalidMemType(u16),
    #[error("Invalid memory attributes {0}")]
    InvalidMemAttributes(u16),
    #[error("Composite offset mismatch")]
    CompositeOffsetMismatch,
    #[error("Invalid endpoint count {0}")]
    UnsupportedEndpointCount(u32),
    #[error("Invalid buffer size")]
    InvalidBufferSize,
    #[error("Malformed descriptor")]
    MalformedDescriptor,
}

impl From<Error> for crate::FfaError {
    fn from(_value: Error) -> Self {
        Self::InvalidParameters
    }
}

/// Memory region handle, used to identify a composite memory region description.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Handle(pub u64);

impl From<[u32; 2]> for Handle {
    fn from(value: [u32; 2]) -> Self {
        Self(((value[1] as u64) << 32) | value[0] as u64)
    }
}

impl From<Handle> for [u32; 2] {
    fn from(value: Handle) -> Self {
        [value.0 as u32, (value.0 >> 32) as u32]
    }
}

impl Handle {
    pub const INVALID: u64 = 0xffff_ffff_ffff_ffff;
}

/// Cacheability attribute of a memory region. Only valid for normal memory.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[repr(u16)]
pub enum Cacheability {
    #[default]
    NonCacheable = Self::NON_CACHEABLE << Self::SHIFT,
    WriteBack = Self::WRITE_BACK << Self::SHIFT,
}

impl TryFrom<u16> for Cacheability {
    type Error = Error;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        match (value >> Self::SHIFT) & Self::MASK {
            Self::NON_CACHEABLE => Ok(Cacheability::NonCacheable),
            Self::WRITE_BACK => Ok(Cacheability::WriteBack),
            _ => Err(Error::InvalidCacheability(value)),
        }
    }
}

impl Cacheability {
    const SHIFT: usize = 2;
    const MASK: u16 = 0b11;
    const NON_CACHEABLE: u16 = 0b01;
    const WRITE_BACK: u16 = 0b11;
}

/// Shareability attribute of a memory region. Only valid for normal memory.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[repr(u16)]
pub enum Shareability {
    #[default]
    NonShareable = Self::NON_SHAREABLE << Self::SHIFT,
    Outer = Self::OUTER << Self::SHIFT,
    Inner = Self::INNER << Self::SHIFT,
}

impl TryFrom<u16> for Shareability {
    type Error = Error;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        match (value >> Self::SHIFT) & Self::MASK {
            Self::NON_SHAREABLE => Ok(Self::NonShareable),
            Self::OUTER => Ok(Self::Outer),
            Self::INNER => Ok(Self::Inner),
            _ => Err(Error::InvalidShareability(value)),
        }
    }
}

impl Shareability {
    const SHIFT: usize = 0;
    const MASK: u16 = 0b11;
    const NON_SHAREABLE: u16 = 0b00;
    const OUTER: u16 = 0b10;
    const INNER: u16 = 0b11;
}

/// Device memory attributes.
#[derive(Debug, Default, Clone, Copy)]
#[repr(u16)]
pub enum DeviceMemAttributes {
    #[default]
    DevnGnRnE = Self::DEV_NGNRNE << Self::SHIFT,
    DevnGnRE = Self::DEV_NGNRE << Self::SHIFT,
    DevnGRE = Self::DEV_NGRE << Self::SHIFT,
    DevGRE = Self::DEV_GRE << Self::SHIFT,
}

impl TryFrom<u16> for DeviceMemAttributes {
    type Error = Error;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        match (value >> Self::SHIFT) & Self::MASK {
            Self::DEV_NGNRNE => Ok(Self::DevnGnRnE),
            Self::DEV_NGNRE => Ok(Self::DevnGnRE),
            Self::DEV_NGRE => Ok(Self::DevnGRE),
            Self::DEV_GRE => Ok(Self::DevGRE),
            _ => Err(Error::InvalidDevMemAttributes(value)),
        }
    }
}

impl DeviceMemAttributes {
    const SHIFT: usize = 2;
    const MASK: u16 = 0b11;
    const DEV_NGNRNE: u16 = 0b00;
    const DEV_NGNRE: u16 = 0b01;
    const DEV_NGRE: u16 = 0b10;
    const DEV_GRE: u16 = 0b11;
}

/// Memory region type.
#[derive(Debug, Default, Clone, Copy)]
pub enum MemType {
    #[default]
    NotSpecified,
    Device(DeviceMemAttributes),
    Normal {
        cacheability: Cacheability,
        shareability: Shareability,
    },
}

impl TryFrom<u16> for MemType {
    type Error = Error;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        match (value >> Self::SHIFT) & Self::MASK {
            Self::NOT_SPECIFIED => Ok(Self::NotSpecified),
            Self::DEVICE => Ok(Self::Device(value.try_into()?)),
            Self::NORMAL => Ok(Self::Normal {
                cacheability: value.try_into()?,
                shareability: value.try_into()?,
            }),
            _ => Err(Error::InvalidMemType(value)),
        }
    }
}

impl From<MemType> for u16 {
    fn from(value: MemType) -> Self {
        match value {
            MemType::NotSpecified => MemType::NOT_SPECIFIED << MemType::SHIFT,
            MemType::Device(attr) => attr as u16 | (MemType::DEVICE << MemType::SHIFT),
            MemType::Normal {
                cacheability,
                shareability,
            } => cacheability as u16 | shareability as u16 | (MemType::NORMAL << MemType::SHIFT),
        }
    }
}

impl MemType {
    const SHIFT: usize = 4;
    const MASK: u16 = 0b11;
    const NOT_SPECIFIED: u16 = 0b00;
    const DEVICE: u16 = 0b01;
    const NORMAL: u16 = 0b10;
}

/// Memory region security attribute.
#[derive(Debug, Default, Clone, Copy, PartialEq)]
#[repr(u16)]
pub enum MemRegionSecurity {
    #[default]
    Secure = Self::SECURE << Self::SHIFT,
    NonSecure = Self::NON_SECURE << Self::SHIFT,
}

impl From<u16> for MemRegionSecurity {
    fn from(value: u16) -> Self {
        match (value >> Self::SHIFT) & Self::MASK {
            Self::SECURE => Self::Secure,
            Self::NON_SECURE => Self::NonSecure,
            _ => panic!(), // The match is exhaustive for a 1-bit value
        }
    }
}

impl MemRegionSecurity {
    const SHIFT: usize = 6;
    const MASK: u16 = 0b1;
    const SECURE: u16 = 0b0;
    const NON_SECURE: u16 = 0b1;
}

/// Memory region attributes descriptor.
#[derive(Debug, Default, Clone, Copy)]
pub struct MemRegionAttributes {
    pub security: MemRegionSecurity,
    pub mem_type: MemType,
}

impl TryFrom<u16> for MemRegionAttributes {
    type Error = Error;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        // bits[15:7]: Reserved (MBZ)
        if value >> 7 == 0 {
            Ok(Self {
                security: value.into(),
                mem_type: value.try_into()?,
            })
        } else {
            Err(Error::InvalidMemAttributes(value))
        }
    }
}

impl From<MemRegionAttributes> for u16 {
    fn from(value: MemRegionAttributes) -> Self {
        value.security as u16 | u16::from(value.mem_type)
    }
}

/// Instruction access permissions of a memory region.
#[derive(Debug, Default, Clone, Copy)]
#[repr(u8)]
pub enum InstuctionAccessPerm {
    #[default]
    NotSpecified = Self::NOT_SPECIFIED << Self::SHIFT,
    NotExecutable = Self::NOT_EXECUTABLE << Self::SHIFT,
    Executable = Self::EXECUTABLE << Self::SHIFT,
}

impl TryFrom<u8> for InstuctionAccessPerm {
    type Error = Error;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match (value >> Self::SHIFT) & Self::MASK {
            Self::NOT_SPECIFIED => Ok(Self::NotSpecified),
            Self::NOT_EXECUTABLE => Ok(Self::NotExecutable),
            Self::EXECUTABLE => Ok(Self::Executable),
            _ => Err(Error::InvalidInstrAccessPerm(value)),
        }
    }
}

impl InstuctionAccessPerm {
    const SHIFT: usize = 2;
    const MASK: u8 = 0b11;
    const NOT_SPECIFIED: u8 = 0b00;
    const NOT_EXECUTABLE: u8 = 0b01;
    const EXECUTABLE: u8 = 0b10;
}

/// Data access permissions of a memory region.
#[derive(Debug, Default, Clone, Copy)]
#[repr(u8)]
pub enum DataAccessPerm {
    #[default]
    NotSpecified = Self::NOT_SPECIFIED << Self::SHIFT,
    ReadOnly = Self::READ_ONLY << Self::SHIFT,
    ReadWrite = Self::READ_WRITE << Self::SHIFT,
}

impl TryFrom<u8> for DataAccessPerm {
    type Error = Error;

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match (value >> Self::SHIFT) & Self::MASK {
            Self::NOT_SPECIFIED => Ok(Self::NotSpecified),
            Self::READ_ONLY => Ok(Self::ReadOnly),
            Self::READ_WRITE => Ok(Self::ReadWrite),
            _ => Err(Error::InvalidDataAccessPerm(value)),
        }
    }
}

impl DataAccessPerm {
    const SHIFT: usize = 0;
    const MASK: u8 = 0b11;
    const NOT_SPECIFIED: u8 = 0b00;
    const READ_ONLY: u8 = 0b01;
    const READ_WRITE: u8 = 0b10;
}

/// Endpoint memory access permissions descriptor.
#[derive(Debug, Default, Clone, Copy)]
pub struct MemAccessPerm {
    pub endpoint_id: u16,
    pub instr_access: InstuctionAccessPerm,
    pub data_access: DataAccessPerm,
    pub flags: u8, // TODO
}

/// Iterator of endpoint memory access permission descriptors.
pub struct MemAccessPermIterator<'a> {
    buf: &'a [u8],
    offset: usize,
    count: usize,
}

impl<'a> MemAccessPermIterator<'a> {
    /// Create an iterator of endpoint memory access permission descriptors from a buffer.
    fn new(buf: &'a [u8], count: usize, offset: usize) -> Result<Self, Error> {
        let Some(total_size) = count
            .checked_mul(size_of::<endpoint_memory_access_descriptor>())
            .and_then(|x| x.checked_add(offset))
        else {
            return Err(Error::InvalidBufferSize);
        };

        if buf.len() < total_size {
            return Err(Error::InvalidBufferSize);
        }

        Ok(Self { buf, offset, count })
    }
}

impl Iterator for MemAccessPermIterator<'_> {
    type Item = Result<MemAccessPerm, Error>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.count > 0 {
            let offset = self.offset;
            self.offset += size_of::<endpoint_memory_access_descriptor>();
            self.count -= 1;

            let Ok(desc_raw) = endpoint_memory_access_descriptor::ref_from_bytes(
                &self.buf[offset..offset + size_of::<endpoint_memory_access_descriptor>()],
            ) else {
                return Some(Err(Error::MalformedDescriptor));
            };

            let instr_access = match desc_raw
                .access_perm_desc
                .memory_access_permissions
                .try_into()
            {
                Ok(v) => v,
                Err(e) => return Some(Err(e)),
            };

            let data_access = match desc_raw
                .access_perm_desc
                .memory_access_permissions
                .try_into()
            {
                Ok(v) => v,
                Err(e) => return Some(Err(e)),
            };

            let desc = MemAccessPerm {
                endpoint_id: desc_raw.access_perm_desc.endpoint_id,
                instr_access,
                data_access,
                flags: desc_raw.access_perm_desc.flags,
            };

            return Some(Ok(desc));
        }

        None
    }
}

/// Constituent memory region descriptor.
#[derive(Debug, Default, Clone, Copy)]
pub struct ConstituentMemRegion {
    pub address: u64,
    pub page_cnt: u32,
}

/// Iterator of constituent memory region descriptors.
pub struct ConstituentMemRegionIterator<'a> {
    buf: &'a [u8],
    offset: usize,
    count: usize,
}

impl<'a> ConstituentMemRegionIterator<'a> {
    /// Create an iterator of constituent memory region descriptors from a buffer.
    fn new(
        buf: &'a [u8],
        region_count: usize,
        total_page_count: u32,
        offset: usize,
    ) -> Result<Self, Error> {
        let descriptor_size = size_of::<constituent_memory_region_descriptor>();

        let Some(total_size) = region_count
            .checked_mul(descriptor_size)
            .and_then(|x| x.checked_add(offset))
        else {
            return Err(Error::InvalidBufferSize);
        };

        if buf.len() < total_size {
            return Err(Error::InvalidBufferSize);
        }

        // Check if the sum of of page counts in the constituent_memory_region_descriptors matches
        // the total_page_count field of the composite_memory_region_descriptor.
        let mut page_count_sum: u32 = 0;
        for desc_offset in
            (offset..offset + descriptor_size * region_count).step_by(descriptor_size)
        {
            let Ok(desc_raw) = constituent_memory_region_descriptor::ref_from_bytes(
                &buf[desc_offset..desc_offset + descriptor_size],
            ) else {
                return Err(Error::MalformedDescriptor);
            };

            page_count_sum = page_count_sum
                .checked_add(desc_raw.page_count)
                .ok_or(Error::MalformedDescriptor)?;
        }

        if page_count_sum != total_page_count {
            return Err(Error::MalformedDescriptor);
        }

        Ok(Self {
            buf,
            offset,
            count: region_count,
        })
    }
}

impl Iterator for ConstituentMemRegionIterator<'_> {
    type Item = Result<ConstituentMemRegion, Error>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.count > 0 {
            let offset = self.offset;
            self.offset += size_of::<constituent_memory_region_descriptor>();
            self.count -= 1;

            let Ok(desc_raw) = constituent_memory_region_descriptor::ref_from_bytes(
                &self.buf[offset..offset + size_of::<constituent_memory_region_descriptor>()],
            ) else {
                return Some(Err(Error::MalformedDescriptor));
            };

            let desc = ConstituentMemRegion {
                address: desc_raw.address,
                page_cnt: desc_raw.page_count,
            };

            return Some(Ok(desc));
        }

        None
    }
}

/// Flags of a memory management transaction.
#[derive(Debug, Default, Clone, Copy)]
pub struct MemTransactionFlags(pub u32);

impl MemTransactionFlags {
    pub const MEM_SHARE_MASK: u32 = 0b11;
    pub const MEM_RETRIEVE_REQ_MASK: u32 = 0b11_1111_1111;
    pub const MEM_RETRIEVE_RESP_MASK: u32 = 0b1_1111;
    pub const ZERO_MEMORY: u32 = 0b1;
    pub const TIME_SLICING: u32 = 0b1 << 1;
    pub const ZERO_AFTER_RELINQ: u32 = 0b1 << 2;
    pub const TYPE_SHARE: u32 = 0b01 << 3;
    pub const TYPE_LEND: u32 = 0b10 << 3;
    pub const TYPE_DONATE: u32 = 0b11 << 3;
    pub const ALIGN_HINT_MASK: u32 = 0b1111 << 5;
    pub const HINT_VALID: u32 = 0b1 << 9;
}

/// Memory transaction decriptor. Used by an Owner/Lender and a Borrower/Receiver in a transaction
/// to donate, lend or share a memory region.
#[derive(Debug, Default)]
pub struct MemTransactionDesc {
    pub sender_id: u16,
    pub mem_region_attr: MemRegionAttributes,
    pub flags: MemTransactionFlags,
    pub handle: Handle,
    pub tag: u64, // TODO
}

impl MemTransactionDesc {
    // Offset from the base of the memory transaction descriptor to the first element in the
    // endpoint memory access descriptor array. Must be 16 byte aligned, but otherwise we're free to
    // choose any value here. Let's just pack it right after the memory transaction descriptor.
    const ENDPOINT_MEM_ACCESS_DESC_OFFSET: usize =
        size_of::<memory_transaction_descriptor>().next_multiple_of(16);

    // The array of constituent memory region descriptors starts right after the composite memory
    // region descriptor
    const CONSTITUENT_ARRAY_OFFSET: usize = size_of::<composite_memory_region_descriptor>();

    /// Serialize a memory transaction descriptor and the related constituent memory region
    /// descriptors and endpoint memory access permission descriptors into a buffer.
    pub fn pack(
        &self,
        constituents: &[ConstituentMemRegion],
        access_descriptors: &[MemAccessPerm],
        buf: &mut [u8],
    ) -> usize {
        let mem_access_desc_size = size_of::<endpoint_memory_access_descriptor>();
        let mem_access_desc_cnt = access_descriptors.len();

        let transaction_desc_raw = memory_transaction_descriptor {
            sender_endpoint_id: self.sender_id,
            memory_region_attributes: self.mem_region_attr.into(),
            flags: self.flags.0,
            handle: self.handle.0,
            tag: self.tag,
            endpoint_mem_access_desc_size: mem_access_desc_size as u32,
            endpoint_mem_access_desc_count: mem_access_desc_cnt as u32,
            endpoint_mem_access_desc_array_offset: Self::ENDPOINT_MEM_ACCESS_DESC_OFFSET as u32,
            reserved1: 0,
            reserved2: 0,
        };

        transaction_desc_raw.write_to_prefix(buf).unwrap();

        // Offset from the base of the memory transaction descriptor to the composite memory region
        // descriptor to which the endpoint access permissions apply.
        let composite_offset = mem_access_desc_cnt
            .checked_mul(mem_access_desc_size)
            .unwrap()
            .checked_add(Self::ENDPOINT_MEM_ACCESS_DESC_OFFSET)
            .unwrap()
            .next_multiple_of(8);

        let mut offset = Self::ENDPOINT_MEM_ACCESS_DESC_OFFSET;

        for desc in access_descriptors {
            let desc_raw = endpoint_memory_access_descriptor {
                access_perm_desc: memory_access_permission_descriptor {
                    endpoint_id: desc.endpoint_id,
                    memory_access_permissions: desc.data_access as u8 | desc.instr_access as u8,
                    flags: desc.flags,
                },
                composite_offset: composite_offset as u32,
                reserved: 0,
            };

            desc_raw.write_to_prefix(&mut buf[offset..]).unwrap();
            offset += mem_access_desc_size;
        }

        let mut total_page_count: u32 = 0;

        offset = composite_offset + Self::CONSTITUENT_ARRAY_OFFSET;
        for constituent in constituents {
            let constituent_raw = constituent_memory_region_descriptor {
                address: constituent.address,
                page_count: constituent.page_cnt,
                reserved: 0,
            };

            constituent_raw.write_to_prefix(&mut buf[offset..]).unwrap();
            offset += size_of::<constituent_memory_region_descriptor>();

            total_page_count = total_page_count
                .checked_add(constituent_raw.page_count)
                .expect("total_page_count overflow");
        }

        let composite_desc_raw = composite_memory_region_descriptor {
            total_page_count,
            address_range_count: constituents.len() as u32,
            reserved: 0,
        };

        composite_desc_raw
            .write_to_prefix(&mut buf[composite_offset..])
            .unwrap();

        offset
    }

    /// Deserialize a memory transaction descriptor from a buffer and return an interator of the
    /// related endpoint memory access permission descriptors and constituent memory region
    /// descriptors, if any.
    pub fn unpack(
        buf: &[u8],
    ) -> Result<
        (
            MemTransactionDesc,
            MemAccessPermIterator,
            Option<ConstituentMemRegionIterator>,
        ),
        Error,
    > {
        let Some(transaction_desc_bytes) = buf.get(0..size_of::<memory_transaction_descriptor>())
        else {
            return Err(Error::InvalidBufferSize);
        };

        let Ok(transaction_desc_raw) =
            memory_transaction_descriptor::ref_from_bytes(transaction_desc_bytes)
        else {
            return Err(Error::MalformedDescriptor);
        };

        if size_of::<endpoint_memory_access_descriptor>()
            != transaction_desc_raw.endpoint_mem_access_desc_size as usize
        {
            return Err(Error::MalformedDescriptor);
        }

        if transaction_desc_raw.endpoint_mem_access_desc_count == 0 {
            return Err(Error::MalformedDescriptor);
        }

        let Some(total_desc_size) = transaction_desc_raw
            .endpoint_mem_access_desc_size
            .checked_mul(transaction_desc_raw.endpoint_mem_access_desc_count)
            .and_then(|x| {
                x.checked_add(transaction_desc_raw.endpoint_mem_access_desc_array_offset)
            })
        else {
            return Err(Error::InvalidBufferSize);
        };

        if buf.len() < total_desc_size as usize {
            return Err(Error::InvalidBufferSize);
        }

        let transaction_desc = MemTransactionDesc {
            sender_id: transaction_desc_raw.sender_endpoint_id,
            mem_region_attr: transaction_desc_raw.memory_region_attributes.try_into()?,
            flags: MemTransactionFlags(transaction_desc_raw.flags),
            handle: Handle(transaction_desc_raw.handle),
            tag: transaction_desc_raw.tag,
        };

        let mut offset = transaction_desc_raw.endpoint_mem_access_desc_array_offset as usize;

        let access_desc_iter = MemAccessPermIterator::new(
            buf,
            transaction_desc_raw.endpoint_mem_access_desc_count as usize,
            offset,
        )?;

        // We have to check the first endpoint memory access descriptor to get the composite offset
        let Ok(desc_raw) = endpoint_memory_access_descriptor::ref_from_bytes(
            &buf[offset..offset + size_of::<endpoint_memory_access_descriptor>()],
        ) else {
            return Err(Error::MalformedDescriptor);
        };

        offset = desc_raw.composite_offset as usize;

        // An offset value of 0 indicates that the endpoint access permissions apply to a memory
        // region description identified by the Handle (i.e. there is no composite descriptor)
        if offset == 0 {
            return Ok((transaction_desc, access_desc_iter, None));
        }

        let Some(composite_desc_bytes) =
            buf.get(offset..offset + size_of::<composite_memory_region_descriptor>())
        else {
            return Err(Error::InvalidBufferSize);
        };

        let Ok(composite_desc_raw) =
            composite_memory_region_descriptor::ref_from_bytes(composite_desc_bytes)
        else {
            return Err(Error::MalformedDescriptor);
        };

        let constituent_iter = ConstituentMemRegionIterator::new(
            buf,
            composite_desc_raw.address_range_count as usize,
            composite_desc_raw.total_page_count,
            offset + Self::CONSTITUENT_ARRAY_OFFSET,
        )?;

        Ok((transaction_desc, access_desc_iter, Some(constituent_iter)))
    }
}

/// Descriptor to relinquish a memory region. Currently only supports specifying a single endpoint.
#[derive(Debug, Default)]
pub struct MemRelinquishDesc {
    pub handle: Handle,
    pub flags: u32,
    pub endpoint: u16,
}

impl TryFrom<&[u8]> for MemRelinquishDesc {
    type Error = Error;

    fn try_from(buf: &[u8]) -> Result<Self, Self::Error> {
        let Some(desc_bytes) = buf.get(0..size_of::<memory_relinquish_descriptor>()) else {
            return Err(Error::InvalidBufferSize);
        };

        let Ok(desc_raw) = memory_relinquish_descriptor::ref_from_bytes(desc_bytes) else {
            return Err(Error::MalformedDescriptor);
        };

        let Some(total_desc_size) = (desc_raw.endpoint_count as usize)
            .checked_mul(size_of::<u16>())
            .and_then(|x| x.checked_add(Self::ENDPOINT_ARRAY_OFFSET))
        else {
            return Err(Error::InvalidBufferSize);
        };

        if buf.len() < total_desc_size {
            return Err(Error::InvalidBufferSize);
        }

        // If the caller is a PE endpoint Borrower, then Endpoint count must equal 1. Currently only
        // this case is supported. The array of endpoint IDs contains only a single element.
        if desc_raw.endpoint_count != 1 {
            return Err(Error::UnsupportedEndpointCount(desc_raw.endpoint_count));
        }

        let endpoint = u16::from_le_bytes([
            buf[Self::ENDPOINT_ARRAY_OFFSET],
            buf[Self::ENDPOINT_ARRAY_OFFSET + 1],
        ]);

        Ok(Self {
            handle: Handle(desc_raw.handle),
            flags: desc_raw.flags, // TODO: validate
            endpoint,
        })
    }
}

impl MemRelinquishDesc {
    const ENDPOINT_ARRAY_OFFSET: usize = size_of::<memory_relinquish_descriptor>();
}

#[cfg(test)]
mod tests {
    use super::*;

    #[allow(dead_code)]
    const MEM_SHARE_FROM_SP1: &[u8] = &[
        0x05, 0x80, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x03, 0x80, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ];

    #[allow(dead_code)]
    const MEM_SHARE_FROM_SP2: &[u8] = &[
        0x06, 0x80, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x05, 0x80, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ];

    #[allow(dead_code)]
    const MEM_RETRIEVE_REQ_FROM_SP1: &[u8] = &[
        0x05, 0x80, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x03, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
    ];

    #[allow(dead_code)]
    const MEM_RETRIEVE_REQ_FROM_SP2: &[u8] = &[
        0x06, 0x80, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x05, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
    ];

    #[allow(dead_code)]
    const MEM_SHARE_FROM_NWD: &[u8] = &[
        0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x03, 0x80, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x22, 0x80, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ];

    #[test]
    fn mem_share() {
        let (transaction_desc, access_desc, constituents) =
            MemTransactionDesc::unpack(MEM_SHARE_FROM_SP1).unwrap();

        println!("transaction desc: {:#x?}", transaction_desc);
        access_desc.for_each(|d| println!("endpont desc: {d:#x?}"));
        constituents
            .unwrap()
            .for_each(|c| println!("constituent desc: {c:#x?}"));
    }
}
