// 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..

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

pub struct RsrvMemAlloc;

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

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

    #[inline]
    pub unsafe fn alloc_zeroed(&mut 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(&mut 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::RsrvMemAllocErr;
    use super::ProtectAttr;
    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_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_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) 
        }
    }
}
