// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! A convenience crate for Zircon VMO objects mapped into memory.

#![deny(missing_docs)]

use {
    fuchsia_runtime::vmar_root_self,
    fuchsia_zircon as zx,
    shared_buffer::SharedBuffer,
    std::ops::{
        Deref,
        DerefMut,
    },
};

/// A safe wrapper around a mapped region of memory.
///
/// Note: this type implements `Deref`/`DerefMut` to the `SharedBuffer`
/// type, which allows reading/writing from the underlying memory.
/// Aside from creation and the `Drop` impl, all of the interesting
/// functionality of this type is offered via `SharedBuffer`.
#[derive(Debug)]
pub struct Mapping {
    buffer: SharedBuffer,
}

impl Deref for Mapping {
    type Target = SharedBuffer;
    fn deref(&self) -> &Self::Target {
        &self.buffer
    }
}

impl DerefMut for Mapping {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.buffer
    }
}

impl Mapping {
    /// Create a `Mapping` and map it in the root address space.
    /// Returns the VMO that was mapped.
    ///
    /// The resulting VMO will not be resizeable.
    pub fn allocate(size: usize) -> Result<(Self, zx::Vmo), zx::Status> {
        let vmo = zx::Vmo::create_with_opts(
            zx::VmoOptions::NON_RESIZABLE,
            size as u64,
        )?;
        let flags = zx::VmarFlags::PERM_READ
            | zx::VmarFlags::PERM_WRITE
            | zx::VmarFlags::MAP_RANGE
            | zx::VmarFlags::REQUIRE_NON_RESIZABLE;
        let mapping = Self::create_from_vmo(&vmo, size, flags)?;
        Ok((
            mapping,
            vmo
        ))
    }

    /// Create a `Mapping` from an existing VMO.
    ///
    /// Requires that the VMO was created with the `NON_RESIZABLE`
    /// option, and returns `ZX_ERR_NOT_SUPPORTED` otherwise.
    pub fn create_from_vmo(vmo: &zx::Vmo, size: usize, flags: zx::VmarFlags)
        -> Result<Self, zx::Status>
    {
        let flags = flags | zx::VmarFlags::REQUIRE_NON_RESIZABLE;
        let addr = vmar_root_self().map(
            0, &vmo, 0, size, flags,
        )?;

        // Safety:
        //
        // The memory behind this `SharedBuffer` is only accessible via
        // methods on `SharedBuffer`.
        //
        // The underlying memory is accessible during any accesses to `SharedBuffer`:
        // - It is only unmapped on `drop`
        // - `SharedBuffer` is never exposed in a way that would allow it to live longer than
        //   the `Mapping` itself
        // - The underlying VMO is non-resizeable.
        let buffer = unsafe { SharedBuffer::new(addr as *mut u8, size) };
        Ok(Mapping { buffer })
    }

    /// Return the size of the mapping.
    pub fn len(&self) -> usize {
        self.buffer.len()
    }
}

impl Drop for Mapping {
    fn drop(&mut self) {
        let (addr, size): (*mut u8, usize) = self.buffer.as_ptr_len();
        let addr = addr as usize;

        // Safety:
        //
        // The memory behind this `SharedBuffer` is only accessible
        // via references to the internal `SharedBuffer`, which must
        // have all been invalidated at this point. The memory is
        // therefore safe to unmap.
        unsafe {
            let _ = vmar_root_self().unmap(addr, size);
        }
    }
}

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

    const PAGE_SIZE: usize = 4096;

    #[test]
    fn test_create() {
        let size = PAGE_SIZE;
        let (mapping, _vmo) = Mapping::allocate(size).unwrap();
        assert_eq!(size, mapping.len());
    }

    #[test]
    fn test_create_from_vmo() {
        let size = PAGE_SIZE;
        let flags = zx::VmarFlags::PERM_READ | zx::VmarFlags::PERM_WRITE;
        {
            // Requires NON_RESIZEABLE
            let vmo = zx::Vmo::create(size as u64).unwrap();
            let status = Mapping::create_from_vmo(&vmo, size, flags).unwrap_err();
            assert_eq!(status, zx::Status::NOT_SUPPORTED);
        }
        {
            let vmo = zx::Vmo::create_with_opts(
                zx::VmoOptions::NON_RESIZABLE,
                size as u64,
            ).unwrap();
            let mapping = Mapping::create_from_vmo(&vmo, size, flags).unwrap();
            assert_eq!(size, mapping.len());
        }
    }

    #[test]
    fn test_mapping_read_write() {
        let size = PAGE_SIZE;
        let (mapping, vmo) = Mapping::allocate(size).unwrap();

        let mut buf = [0; 128];

        // We can write to the Vmo, and see the results in the mapping.
        let s = b"Hello world";
        vmo.write(s, 0).unwrap();
        let slice = &mut buf[0..s.len()];
        mapping.read(slice);
        assert_eq!(s, slice);

        // We can write to the mapping, and see the results in the Vmo.
        let s = b"Goodbye world";
        mapping.write(s);
        let slice = &mut buf[0..s.len()];
        vmo.read(slice, 0).unwrap();
        assert_eq!(s, slice);
    }
}
