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

use fidl_fuchsia_hardware_ethernet as sys;
use fuchsia_zircon as zx;
use shared_buffer::SharedBuffer;
use std::fmt;
use std::sync::{Arc, Mutex};

#[repr(C)]
#[derive(Debug)]
pub struct FifoEntry {
    pub offset: u32,
    pub length: u16,
    pub flags: u16,
    cookie: u64,
}

unsafe impl fuchsia_async::FifoEntry for FifoEntry {}

impl From<sys::FifoEntry> for FifoEntry {
    fn from(
        sys::FifoEntry {
            offset,
            length,
            flags,
            cookie,
        }: sys::FifoEntry,
    ) -> Self {
        Self {
            offset,
            length,
            flags,
            cookie,
        }
    }
}

fn fifo_entry(offset: u32, length: u16) -> FifoEntry {
    FifoEntry {
        offset,
        length,
        flags: 0,
        cookie: 0,
    }
}

pub struct RxBuffer {
    data: SharedBuffer,
    offset: usize,
    buflist: Arc<Mutex<BufferMap>>,
}

impl RxBuffer {
    pub fn len(&self) -> usize {
        self.data.len()
    }

    pub fn read(&self, dst: &mut [u8]) -> usize {
        self.data.read(dst)
    }
}

impl Drop for RxBuffer {
    fn drop(&mut self) {
        self.buflist.lock().unwrap().set_bit(self.offset);
    }
}

impl fmt::Debug for RxBuffer {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        f.debug_struct("RxBuffer")
            .field("offset", &self.offset)
            .field("len", &self.data.len())
            .finish()
    }
}

pub struct TxBuffer<'a> {
    data: SharedBuffer,
    offset: usize,
    length: usize,
    marker: ::std::marker::PhantomData<&'a BufferPool>,
}

impl<'a> TxBuffer<'a> {
    pub fn write(&mut self, src: &[u8]) -> usize {
        self.length = self.data.write(src);
        self.length
    }

    pub fn entry(self) -> FifoEntry {
        FifoEntry {
            offset: self.offset as u32,
            length: self.length as u16,
            flags: 0,
            cookie: 0,
        }
    }
}

/// A BufferPool represents a pool of memory that may be parceled out and used as buffers for
/// communicating with an Ethernet device.
///
/// Transmit and receive buffers are currently tracked separately. (TODO(tkilbourn): explain why)
/// In the memory pool, receive buffers are allocated first, followed by the transmit buffers. The
/// available/in-flight indexes represent the index within the given type of buffer, not the global
/// buffer pool.
pub struct BufferPool {
    /// The pointer and length representing the entire memory available to the pool.
    base: *mut u8,
    len: usize,
    /// The total number of buffers of each type.
    num_buffers: usize,
    /// The size of a buffer in the pool.
    buffer_size: usize,
    /// The offsets of the available buffers within the pool.
    rx_avail: Arc<Mutex<BufferMap>>,
    tx_avail: BufferMap,
    /// The offsets of buffers sent to another process.
    rx_in_flight: BufferMap,
    tx_in_flight: BufferMap,
}

// The only field within a BufferPool which is not already Send is the
// `base: *mut u8` field. We use that field as the base from which to calculate
// offsets which are obtained through thread-safe mechanisms (accessing the
// other fields of the struct, all of which are Send). Thus, there is no race
// condition. Further, since we never give out overlapping memory, it is safe
// for multiple different threads to hold onto memory vended by a BufferPool.
// Additionally, since the VMO is expected to be shared with another process
// anyways, we already expect it to be subject to unsynchronized manipulation.
// TODO(tkilbourn): write more tests (and/or proofs) that we don't give out overlapping memory
unsafe impl Send for BufferPool{}

impl BufferPool {
    /// Create a new `BufferPool` out of the given VMO, with each buffer having length
    /// `buffer_size`.
    pub fn new(vmo: zx::Vmo, buffer_size: usize) -> Result<BufferPool, zx::Status> {
        let len = vmo.get_size()? as usize;
        let mapped = zx::Vmar::root_self().map(
            0,
            &vmo,
            0,
            len,
            zx::VmarFlags::PERM_READ | zx::VmarFlags::PERM_WRITE,
        )?;
        let num_buffers = len / buffer_size / 2;
        let mut rx_avail = BufferMap::new(num_buffers);
        for i in 0..num_buffers {
            rx_avail.set_bit(i);
        }
        let mut tx_avail = BufferMap::new(num_buffers);
        for i in 0..num_buffers {
            tx_avail.set_bit(i);
        }
        Ok(BufferPool {
            base: mapped as *mut u8,
            len,
            num_buffers,
            rx_avail: Arc::new(Mutex::new(rx_avail)),
            tx_avail,
            rx_in_flight: BufferMap::new(num_buffers),
            tx_in_flight: BufferMap::new(num_buffers),
            buffer_size,
        })
    }

    /// Allocate a receive buffer and return the Ethernet fifo entry needed to queue it for the
    /// driver.
    pub fn alloc_rx_buffer(&mut self) -> Option<FifoEntry> {
        let mut rx_avail = self.rx_avail.lock().unwrap();
        let offset = rx_avail.find_first_set()?;
        rx_avail.clear_bit(offset);
        self.rx_in_flight.set_bit(offset);
        let fifo_offset = offset * self.buffer_size;
        Some(fifo_entry(fifo_offset as u32, self.buffer_size as u16))
    }

    /// Allocate a transmit buffer that may later be queued to the Ethernet device.
    pub fn alloc_tx_buffer<'a>(&'a mut self) -> Option<TxBuffer<'a>> {
        let offset = self.tx_avail.find_first_set()?;
        self.tx_avail.clear_bit(offset);
        self.tx_in_flight.set_bit(offset);
        let fifo_offset = (self.num_buffers + offset) * self.buffer_size;
        Some(TxBuffer {
            data: unsafe {
                SharedBuffer::new(self.base.offset(fifo_offset as isize), self.buffer_size)
            },
            offset: fifo_offset,
            length: 0,
            marker: ::std::marker::PhantomData,
        })
    }

    /// Return a transmit buffer returned by the Ethernet device via the tx fifo. The index is
    /// determined by the offset from the `base` of the pool.
    pub fn release_tx_buffer(&mut self, fifo_offset: usize) {
        assert!(fifo_offset % self.buffer_size == 0);
        let offset = fifo_offset / self.buffer_size - self.num_buffers;
        assert!(self.tx_in_flight.get_bit(offset));
        self.tx_avail.set_bit(offset);
        self.tx_in_flight.clear_bit(offset);
    }

    /// Create an `RxBuffer` from the offset+len obtained from the rx fifo from the Ethernet
    /// device. The buffer is no longer considered either available or in-flight.
    pub fn map_rx_buffer(&mut self, fifo_offset: usize, len: usize) -> RxBuffer {
        assert!(fifo_offset % self.buffer_size == 0);
        assert!(len <= self.buffer_size);
        let offset = fifo_offset / self.buffer_size;
        assert!(self.rx_in_flight.get_bit(offset));
        self.rx_in_flight.clear_bit(offset);
        RxBuffer {
            data: unsafe { SharedBuffer::new(self.base.offset(fifo_offset as isize), len) },
            offset,
            buflist: Arc::clone(&self.rx_avail),
        }
    }
}

impl fmt::Debug for BufferPool {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        f.debug_struct("BufferPool")
            .field("base", &self.base)
            .field("len", &self.len)
            .field("num_buffers", &self.num_buffers)
            .field("buffer_size", &self.buffer_size)
            .field("rx_avail", &self.rx_avail)
            .field("tx_avail", &self.tx_avail)
            .field("rx_in_flight", &self.rx_in_flight)
            .field("tx_in_flight", &self.tx_in_flight)
            .finish()
    }
}

impl Drop for BufferPool {
    fn drop(&mut self) {
        unsafe {
            zx::Vmar::root_self()
                .unmap(self.base as usize, self.len)
                .unwrap();
        }
    }
}

/// A bitmap used to store buffer status.
#[derive(Debug)]
struct BufferMap {
    map: Vec<u64>,
    len: usize,
}

impl BufferMap {
    /// Create a new `BufferMap` with the given number of bits. The underlying storage may use more
    /// bits, but these are not accessible.
    fn new(size: usize) -> BufferMap {
        assert!(size < usize::max_value() - 63);
        let byte_size = (size + 63) / 64;
        BufferMap {
            map: vec![0; byte_size],
            len: size,
        }
    }

    /// Set the given bit. Panics if the bit is out of the range.
    fn set_bit(&mut self, bit: usize) {
        assert!(bit < self.len, "bit index out of bounds");
        let byte_offset = bit / 64;
        let bit_offset = bit % 64;
        self.map[byte_offset] |= 1 << bit_offset;
    }

    /// Clear the given bit. Panics if the bit is out of range.
    fn clear_bit(&mut self, bit: usize) {
        assert!(bit < self.len, "bit index out of bounds");
        let byte_offset = bit / 64;
        let bit_offset = bit % 64;
        self.map[byte_offset] &= !(1 << bit_offset);
    }

    /// Check whether the given bit is set. Panics if the bit is out of range.
    fn get_bit(&self, bit: usize) -> bool {
        assert!(bit < self.len, "bit index out of bounds");
        let byte_offset = bit / 64;
        let bit_offset = bit % 64;
        self.map[byte_offset] & (1 << bit_offset) != 0
    }

    /// Finds the lowest index bit that is set in the map or `None` if all bits are cleared. The
    /// bit is *not* cleared after returning from this method.
    fn find_first_set(&self) -> Option<usize> {
        for (i, byte) in self.map.iter().enumerate() {
            let ntz = byte.trailing_zeros();
            if ntz < 64 {
                return Some(i * 64 + ntz as usize);
            }
        }
        None
    }
}

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

    #[test]
    fn test_new_buffer_map() {
        let map = BufferMap::new(1);
        assert_eq!(1, map.map.len());
        assert_eq!(1, map.len);

        let map = BufferMap::new(64);
        assert_eq!(1, map.map.len());
        assert_eq!(64, map.len);

        let map = BufferMap::new(65);
        assert_eq!(2, map.map.len());
        assert_eq!(65, map.len);
    }

    #[test]
    fn test_set_bit() {
        let mut map = BufferMap::new(100);
        assert_eq!(&[0, 0], &map.map[..]);

        map.set_bit(0);
        assert_eq!(&[1, 0], &map.map[..]);

        map.set_bit(7);
        assert_eq!(&[0b1000_0001, 0], &map.map[..]);

        map.set_bit(7);
        assert_eq!(&[0b1000_0001, 0], &map.map[..]);

        map.set_bit(64);
        assert_eq!(&[0b1000_0001, 1], &map.map[..]);

        map.set_bit(99);
        assert_eq!(&[0b1000_0001, (1 << 35) | 1], &map.map[..]);
    }

    #[test]
    fn test_clear_bit() {
        let mut map = BufferMap::new(100);
        map.map[0] = 0xff;

        map.clear_bit(0);
        assert_eq!(&[0b1111_1110, 0], &map.map[..]);

        map.clear_bit(7);
        assert_eq!(&[0b0111_1110, 0], &map.map[..]);

        map.clear_bit(64);
        assert_eq!(&[0b0111_1110, 0], &map.map[..]);

        map.map[1] = 0x7f;

        map.clear_bit(64);
        assert_eq!(&[0b0111_1110, 0b0111_1110], &map.map[..]);

        map.clear_bit(70);
        assert_eq!(&[0b0111_1110, 0b0011_1110], &map.map[..]);
    }

    #[test]
    fn test_get_bit() {
        let mut map = BufferMap::new(100);

        map.map[0] = 1;
        assert!(map.get_bit(0));
        assert!(!map.get_bit(1));

        map.map[0] = 1 << 63;
        assert!(!map.get_bit(62));
        assert!(map.get_bit(63));
        assert!(!map.get_bit(64));

        map.map[0] = 0;
        map.map[1] = 1;
        assert!(!map.get_bit(63));
        assert!(map.get_bit(64));
        assert!(!map.get_bit(65));

        map.map[1] = 1 << 35;
        assert!(!map.get_bit(98));
        assert!(map.get_bit(99));
    }

    #[test]
    fn test_find_first_set() {
        let mut map = BufferMap::new(100);

        assert_eq!(None, map.find_first_set());

        map.set_bit(0);
        assert_eq!(Some(0), map.find_first_set());

        map.clear_bit(0);
        map.set_bit(1);
        assert_eq!(Some(1), map.find_first_set());

        map.set_bit(63);
        assert_eq!(Some(1), map.find_first_set());

        map.clear_bit(1);
        assert_eq!(Some(63), map.find_first_set());

        map.set_bit(64);
        assert_eq!(Some(63), map.find_first_set());

        map.clear_bit(63);
        assert_eq!(Some(64), map.find_first_set());

        map.set_bit(99);
        assert_eq!(Some(64), map.find_first_set());

        map.clear_bit(64);
        assert_eq!(Some(99), map.find_first_set());

        map.set_bit(5);
        assert_eq!(Some(5), map.find_first_set());
    }

    #[test]
    #[should_panic]
    fn test_set_bit_oob() {
        let mut map = BufferMap::new(1);
        map.set_bit(1);
    }

    #[test]
    #[should_panic]
    fn test_clear_bit_oob() {
        let mut map = BufferMap::new(1);
        map.clear_bit(1);
    }

    #[test]
    #[should_panic]
    fn test_get_bit_oob() {
        let map = BufferMap::new(1);
        let _ = map.get_bit(1);
    }
}
