// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License..

pub use self::platform::*;
use core::fmt;
use core::ptr::NonNull;

pub struct RsrvMemAlloc;

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ProtectAttr {
    Read,
    ReadWrite,
    ReadExec,
    ReadWriteExec,
}

impl RsrvMemAlloc {
    
    /// Allocate a range of EPC memory from the reserved memory area
    ///
    /// # Parameters
    ///
    /// **count**
    ///
    /// Count of pages to allocate region
    ///
    /// # Return value
    ///
    /// Starting address of the new allocated memory area on success;
    ///
    #[inline]
    pub unsafe fn alloc(&self, count: u32) -> Result<NonNull<u8>, RsrvMemAllocErr> {
        NonNull::new(platform::alloc(count)).ok_or(RsrvMemAllocErr)
    }

    /// Allocate a range of EPC memory with a fixed address from the reserved memory area
    ///
    /// # Parameters
    ///
    /// **addr**
    /// 
    /// The desired starting address to allocate the reserved memory. Should be page aligned.
    /// 
    /// **count**
    ///
    /// Count of pages to allocate region
    ///
    /// # Return value
    ///
    /// Starting address of the new allocated memory area on success;
    ///
    #[inline]
    pub unsafe fn alloc_with_addr(&self, addr: NonNull<u8>, count: u32) -> Result<NonNull<u8>, RsrvMemAllocErr> {
        NonNull::new(platform::alloc_with_addr(addr.as_ptr(), count)).ok_or(RsrvMemAllocErr)
    }

    #[inline]
    pub unsafe fn alloc_zeroed(&self, count: u32) -> Result<NonNull<u8>, RsrvMemAllocErr> {
        NonNull::new(platform::alloc_zeroed(count)).ok_or(RsrvMemAllocErr)
    }

    /// Free a range of EPC memory from the reserved memory area
    ///
    /// # Parameters
    ///
    /// ** ptr**
    ///
    /// Starting address of region to be freed. Page aligned.
    ///
    /// **count**
    ///
    /// Count of pages to allocate region
    ///
    #[inline]
    pub unsafe fn dealloc(&self, addr: NonNull<u8>, count: u32) -> Result<(), RsrvMemAllocErr> {
        platform::dealloc(addr.as_ptr(), count)
    }

    /// Modify the access permissions of the pages in the reserved memory area.
    ///
    /// # Parameters
    ///
    /// # Parameters
    ///
    /// ** ptr**
    ///
    /// Starting address of region to be freed. Page aligned.
    ///
    /// **count**
    ///
    /// Count of pages to allocate region
    ///
    /// **port**
    ///
    /// The target memory protection.
    ///
    #[inline]
    pub unsafe fn protect(
        &self,
        addr: NonNull<u8>,
        count: u32,
        prot: ProtectAttr,
    ) -> Result<(), RsrvMemAllocErr> {
        platform::protect(addr.as_ptr(), count, prot)
    }
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct RsrvMemAllocErr;

impl fmt::Display for RsrvMemAllocErr {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("reserves memory allocation failed")
    }
}

mod platform {
    use super::ProtectAttr;
    use super::RsrvMemAllocErr;
    use core::ffi::c_void;
    use core::ptr;

    const SGX_PROT_READ: u32 = 0x1;
    const SGX_PROT_WRITE: u32 = 0x2;
    const SGX_PROT_EXEC: u32 = 0x4;
    const SE_PAGE_SIZE: usize = 0x1000;

    type size_t = usize;
    type int32_t = i32;
    type sgx_status_t = u32;

    extern "C" {
        pub fn sgx_alloc_rsrv_mem(length: size_t) -> *mut c_void;
        pub fn sgx_alloc_rsrv_mem_ex(desired_addr: *const c_void, length: size_t) -> *mut c_void;
        pub fn sgx_free_rsrv_mem(addr: *const c_void, length: size_t) -> int32_t;
        pub fn sgx_tprotect_rsrv_mem(
            addr: *const c_void,
            length: size_t,
            prot: i32,
        ) -> sgx_status_t;
    }

    #[inline]
    pub unsafe fn alloc(count: u32) -> *mut u8 {
        sgx_alloc_rsrv_mem(count as usize * SE_PAGE_SIZE) as *mut u8
    }

    #[inline]
    pub unsafe fn alloc_with_addr(addr: *mut u8, count: u32) -> *mut u8 {
        sgx_alloc_rsrv_mem_ex(addr as *const c_void, count as usize * SE_PAGE_SIZE) as *mut u8
    }

    #[inline]
    pub unsafe fn alloc_zeroed(count: u32) -> *mut u8 {
        let raw = alloc(count);
        if !raw.is_null() {
            ptr::write_bytes(raw, 0, count as usize * SE_PAGE_SIZE);
        }
        raw
    }

    #[inline]
    pub unsafe fn dealloc(addr: *mut u8, count: u32) -> Result<(), RsrvMemAllocErr> {
        if sgx_free_rsrv_mem(addr as *const c_void, count as usize * SE_PAGE_SIZE) == 0 {
            Ok(())
        } else {
            Err(RsrvMemAllocErr)
        }
    }

    #[inline]
    pub unsafe fn protect(
        addr: *mut u8,
        count: u32,
        prot: ProtectAttr,
    ) -> Result<(), RsrvMemAllocErr> {
        let attr = match prot {
            ProtectAttr::Read => SGX_PROT_READ,
            ProtectAttr::ReadWrite => SGX_PROT_READ | SGX_PROT_WRITE,
            ProtectAttr::ReadExec => SGX_PROT_READ | SGX_PROT_EXEC,
            ProtectAttr::ReadWriteExec => SGX_PROT_READ | SGX_PROT_WRITE | SGX_PROT_EXEC,
        };
        if sgx_tprotect_rsrv_mem(
            addr as *const c_void,
            count as usize * SE_PAGE_SIZE,
            attr as i32,
        ) == 0
        {
            Ok(())
        } else {
            Err(RsrvMemAllocErr)
        }
    }
}
