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

//! Implementation of a pseudo file trait backed by read and/or write callbacks and a buffer.
//!
//! Read callback, if any, is called when the connection to the file is first opened and
//! pre-populates a buffer that will be used to when serving this file content over this particular
//! connection.  Read callback is ever called once.
//!
//! Write callback, if any, is called when the connection is closed if the file content was ever
//! modified while the connection was open.  Modifications are: write() calls or opening a file for
//! writing with the OPEN_FLAG_TRUNCATE flag set.
//!
//! First write operation will reset the seek position and empty the buffer.  Any subsequent read
//! operations will read from the same buffer, returning the data that was already written.  This
//! quirk in behaviour is in order to simplify the read()/write() scenarios.
//!
//! Main use case for the pseudo files that are both readable and writeable is the exposure of the
//! component configuration parameters.  In this case when the configuration value is read it is
//! always presented in a canonical format, but when it is written, multiple formats could be used.
//! As a consequence, when the new value length could shorter than the current value (and when
//! different formats are supported it is more likely), besides just writing new file content one
//! would also need to truncate the file.  As we treat our configuration values as atomic, we
//! consider the scenario of an incremental edit less likely, so we truncate automatically.
//!
//! Thinking again about the above, it seems like an unnecessary complication.  When someone wants
//! to just update the value, they can open with OPEN_FLAG_TRUNCATE flag (as does shell when using
//! output redirection) and when the scenario is to read and to write, there is a Truncate() call
//! that sets new file size.  This would remove the quirk and make the file behave more like all
//! the other files.

#![warn(missing_docs)]

use {
    crate::common::send_on_open_with_error,
    crate::directory_entry::{DirectoryEntry, EntryInfo},
    failure::Error,
    fidl::encoding::OutOfLine,
    fidl::endpoints::ServerEnd,
    fidl_fuchsia_io::{
        FileMarker, FileObject, FileRequest, FileRequestStream, NodeAttributes, NodeInfo,
        NodeMarker, SeekOrigin, DIRENT_TYPE_FILE, INO_UNKNOWN, MODE_PROTECTION_MASK,
        MODE_TYPE_DIRECTORY, MODE_TYPE_FILE, OPEN_FLAG_APPEND, OPEN_FLAG_DESCRIBE,
        OPEN_FLAG_DIRECTORY, OPEN_FLAG_TRUNCATE, OPEN_RIGHT_READABLE, OPEN_RIGHT_WRITABLE,
    },
    fuchsia_zircon::{
        sys::{ZX_ERR_NOT_SUPPORTED, ZX_OK},
        Status,
    },
    futures::{
        future::FusedFuture,
        stream::{FuturesUnordered, Stream, StreamExt, StreamFuture},
        task::LocalWaker,
        Future, Poll,
    },
    libc::{S_IRUSR, S_IWUSR},
    std::{io::Write, iter, iter::ExactSizeIterator, marker::Unpin, mem, pin::Pin},
    void::Void,
};

/// A base trait for all the pseudo files.  Most clients will probably just use the DirectoryEntry
/// trait to deal with the pseudo files uniformly.
pub trait PseudoFile: DirectoryEntry {}

// TODO: When trait aliases are implemented (rust-lang/rfcs#1733)
// trait OnReadHandler = FnMut() -> Result<Vec<u8>, Status>;
// trait OnWriteHandler = FnMut(Vec<u8>) -> Result<(), Status>;

/// POSIX emulation layer access attributes set by default for files created with read_only().
pub const DEFAULT_READ_ONLY_PROTECTION_ATTRIBUTES: u32 = S_IRUSR;

/// Creates a new read-only `PseudoFile` backed by the specified read handler.
///
/// The handler is called every time a read operation is performed on the file.  It is only allowed
/// to read at offset 0, and all of the content returned by the handler is returned by the read
/// operation.  Subsequent reads act the same - there is no seek position, nor ability to read
/// content in chunks.
pub fn read_only<OnRead>(on_read: OnRead) -> impl PseudoFile
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
{
    read_only_attr(on_read, DEFAULT_READ_ONLY_PROTECTION_ATTRIBUTES)
}

/// See [`read_only()`].  Wraps the callback, allowing it to return a String instead of a Vec<u8>,
/// but otherwise behaves identical to #read_only().
pub fn read_only_str<OnReadStr>(mut on_read: OnReadStr) -> impl PseudoFile
where
    OnReadStr: FnMut() -> Result<String, Status>,
{
    PseudoFileImpl::<_, fn(Vec<u8>) -> Result<(), Status>>::new(
        Some(move || on_read().map(|content| content.into_bytes())),
        0,
        None,
        DEFAULT_READ_ONLY_PROTECTION_ATTRIBUTES,
    )
}

/// Same as [`read_only()`] but also allows to select custom attributes for the POSIX emulation
/// layer.  Note that only the MODE_PROTECTION_MASK part of the protection_attributes argument will
/// be stored.
pub fn read_only_attr<OnRead>(on_read: OnRead, protection_attributes: u32) -> impl PseudoFile
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
{
    PseudoFileImpl::<_, fn(Vec<u8>) -> Result<(), Status>>::new(
        Some(on_read),
        0,
        None,
        protection_attributes & MODE_PROTECTION_MASK,
    )
}

/// POSIX emulation layer access attributes set by default for files created with write_only().
pub const DEFAULT_WRITE_ONLY_PROTECTION_ATTRIBUTES: u32 = S_IWUSR;

/// Creates a new write-only `PseudoFile` backed by the specified write handler.
///
/// The handler is called every time a write operation is performed on the file.  It is only
/// allowed to write at offset 0, and all of the new content should be provided to a single write
/// operation.  Subsequent writes act the same - there is no seek position, nor ability to write
/// content in chunks.
pub fn write_only<OnWrite>(capacity: u64, on_write: OnWrite) -> impl PseudoFile
where
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    write_only_attr(capacity, on_write, DEFAULT_WRITE_ONLY_PROTECTION_ATTRIBUTES)
}

/// See [`write_only()`].  Only allows valid UTF-8 content to be written into the file.  Written
/// bytes are converted into a string instance an std::str::from_utf8() call, and the passed to the
/// handler.
pub fn write_only_str<OnWriteStr>(capacity: u64, mut on_write: OnWriteStr) -> impl PseudoFile
where
    OnWriteStr: FnMut(String) -> Result<(), Status>,
{
    PseudoFileImpl::<fn() -> Result<Vec<u8>, Status>, _>::new(
        None,
        capacity,
        Some(move |bytes: Vec<u8>| match String::from_utf8(bytes) {
            Ok(content) => on_write(content),
            Err(_) => Err(Status::INVALID_ARGS),
        }),
        DEFAULT_WRITE_ONLY_PROTECTION_ATTRIBUTES,
    )
}

/// Same as [`write_only()`] but also allows to select custom attributes for the POSIX emulation
/// layer.  Note that only the MODE_PROTECTION_MASK part of the protection_attributes argument will
/// be stored.
pub fn write_only_attr<OnWrite>(
    capacity: u64, on_write: OnWrite, protection_attributes: u32,
) -> impl PseudoFile
where
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    PseudoFileImpl::<fn() -> Result<Vec<u8>, Status>, _>::new(
        None,
        capacity,
        Some(on_write),
        protection_attributes & MODE_PROTECTION_MASK,
    )
}

/// POSIX emulation layer access attributes set by default for files created with read_write().
pub const DEFAULT_READ_WRITE_PROTECTION_ATTRIBUTES: u32 =
    DEFAULT_READ_ONLY_PROTECTION_ATTRIBUTES | DEFAULT_WRITE_ONLY_PROTECTION_ATTRIBUTES;

/// Creates new `PseudoFile` backed by the specified read and write handlers.
///
/// The read handler is called every time a read operation is performed on the file.  It is only
/// allowed to read at offset 0, and all of the content returned by the handler is returned by the
/// read operation.  Subsequent reads act the same - there is no seek position, nor ability to read
/// content in chunks.
///
/// The write handler is called every time a write operation is performed on the file.  It is only
/// allowed to write at offset 0, and all of the new content should be provided to a single write
/// operation.  Subsequent writes act the same - there is no seek position, nor ability to write
/// content in chunks.
pub fn read_write<OnRead, OnWrite>(
    on_read: OnRead, capacity: u64, on_write: OnWrite,
) -> impl PseudoFile
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    read_write_attr(
        on_read,
        capacity,
        on_write,
        DEFAULT_READ_WRITE_PROTECTION_ATTRIBUTES,
    )
}

/// See [`read_write()`].  Wraps the read callback, allowing it to return a [`String`] instead of a
/// [`Vec<u8>`].  Wraps the write callback, only allowing valid UTF-8 content to be written into
/// the file.  Written bytes are converted into a string instance an [`std::str::from_utf8()`]
/// call, and the passed to the handler.
/// In every other aspect behaves just like [`read_write()`].
pub fn read_write_str<OnReadStr, OnWriteStr>(
    mut on_read: OnReadStr, capacity: u64, mut on_write: OnWriteStr,
) -> impl PseudoFile
where
    OnReadStr: FnMut() -> Result<String, Status>,
    OnWriteStr: FnMut(String) -> Result<(), Status>,
{
    PseudoFileImpl::new(
        Some(move || on_read().map(|content| content.into_bytes())),
        capacity,
        Some(move |bytes: Vec<u8>| match String::from_utf8(bytes) {
            Ok(content) => on_write(content),
            Err(_) => Err(Status::INVALID_ARGS),
        }),
        DEFAULT_READ_WRITE_PROTECTION_ATTRIBUTES,
    )
}

/// Same as [`read_write()`] but also allows to select custom attributes for the POSIX emulation
/// layer.  Note that only the MODE_PROTECTION_MASK part of the protection_attributes argument will
/// be stored.
pub fn read_write_attr<OnRead, OnWrite>(
    on_read: OnRead, capacity: u64, on_write: OnWrite, protection_attributes: u32,
) -> impl PseudoFile
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    PseudoFileImpl::new(
        Some(on_read),
        capacity,
        Some(on_write),
        protection_attributes & MODE_PROTECTION_MASK,
    )
}

struct FileConnection {
    requests: FileRequestStream,
    /// Either the "flags" value passed into [`DirectoryEntry::open()`], or the "flags" value
    /// passed into FileRequest::Clone().
    flags: u32,
    /// Seek position.  Next byte to be read or written within the buffer.  This might be beyond
    /// the current size of buffer, matching POSIX:
    ///
    ///     http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html
    ///
    /// It will cause the buffern to be extended with zeroes (if necessary) when write() is called.
    // While the content in the buffer vector uses usize for the size, it is easier to use u64 to
    // match the FIDL bindings API.  Pseudo files are not expected to cross the 2^64 bytes size
    // limit.  And all the code is much simpler when we just assume that usize is the same as u64.
    // Should we need to port to a 128 bit platform, there are static assertions in the code that
    // would fail.
    seek: u64,
    /// Per connection buffer.  See module documentation for details.
    buffer: Vec<u8>,
    /// Starts as false, and causes the [`on_write()`] to be called when the connection is closed
    /// if set to true during the lifetime of the connection.
    was_written: bool,
}

impl FileConnection {
    /// Creates a new [`FileConnection`] instance, immediately wrapping it in a [`StreamFuture`].
    /// This is how [`FileConnection`]s are used in the pseudo file implementation.
    fn as_stream_future(
        requests: FileRequestStream, flags: u32, buffer: Vec<u8>, was_written: bool,
    ) -> StreamFuture<FileConnection> {
        (FileConnection {
            requests,
            flags,
            seek: 0,
            buffer,
            was_written,
        })
        .into_future()
    }
}

/// Allow [`FileConnection`] to be wrapped in a [`StreamFuture`], to be further contained inside
/// [`FuturesUnordered`].
impl Stream for FileConnection {
    // We are just proxying the FileRequestStream requests.
    type Item = <FileRequestStream as Stream>::Item;

    fn poll_next(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Option<Self::Item>> {
        self.requests.poll_next_unpin(lw)
    }
}

struct PseudoFileImpl<OnRead, OnWrite>
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    /// A handler to be invoked to populate the content buffer when a connection to this file is
    /// opened.
    on_read: Option<OnRead>,

    /// Maximum size the buffer that holds the value written into this file can grow to.  When the
    /// buffer is populated by a the [`on_read`] handler, this restriction is not enforced.  The
    /// maximum size of the buffer passed into [`on_write`] is the maximum of the size of the
    /// buffer that [`on_read`] have returnd and this value.
    capacity: u64,

    /// A handler to be invoked to "update" the file content, if it was modified during a
    /// connection lifetime.
    on_write: Option<OnWrite>,

    /// MODE_PROTECTION_MASK attributes returned by this file through io.fild:Node::GetAttr.  They
    /// have no meaning for the file operation itself, but may have consequences to the POSIX
    /// emulation layer - for example, it makes sense to remove the read flags from a read-only
    /// file.  This field should only have set bits in the MODE_PROTECTION_MASK part.
    protection_attributes: u32,

    /// All the currently open connections for this file.
    connections: FuturesUnordered<StreamFuture<FileConnection>>,
}

/// Return type for PseudoFileImpl::handle_request().
enum ConnectionState {
    Alive,
    Closed,
}

/// We assume that usize/isize and u64/i64 are of the same size in a few locations in code.  This
/// macro is used to mark the locations of those assumptions.
/// Copied from
///
///     https://docs.rs/static_assertions/0.2.5/static_assertions/macro.assert_eq_size.html
///
macro_rules! assert_eq_size {
    ($x:ty, $($xs:ty),+ $(,)*) => {
        $(let _ = core::mem::transmute::<$x, $xs>;)+
    };
}

impl<OnRead, OnWrite> PseudoFileImpl<OnRead, OnWrite>
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    fn new(
        on_read: Option<OnRead>, capacity: u64, on_write: Option<OnWrite>,
        protection_attributes: u32,
    ) -> Self {
        PseudoFileImpl {
            on_read,
            capacity,
            on_write,
            protection_attributes,
            connections: FuturesUnordered::new(),
        }
    }

    fn validate_flags(&mut self, parent_flags: u32, flags: u32) -> Result<(), Status> {
        if flags & OPEN_FLAG_DIRECTORY != 0 {
            return Err(Status::NOT_DIR);
        }

        let allowed_flags = OPEN_FLAG_DESCRIBE
            | if self.on_read.is_some() {
                OPEN_RIGHT_READABLE
            } else {
                0
            }
            | if self.on_write.is_some() {
                OPEN_RIGHT_WRITABLE | OPEN_FLAG_TRUNCATE
            } else {
                0
            };

        let prohibited_flags = (0 | if self.on_read.is_some() {
                OPEN_FLAG_TRUNCATE
            } else {
                0
            } | if self.on_write.is_some() {
                OPEN_FLAG_APPEND
            } else {
                0
            })
            // allowed_flags takes precedence over prohibited_flags.
            & !allowed_flags;

        if flags & OPEN_RIGHT_READABLE != 0 && parent_flags & OPEN_RIGHT_READABLE == 0 {
            return Err(Status::ACCESS_DENIED);
        }

        if flags & OPEN_RIGHT_WRITABLE != 0 && parent_flags & OPEN_RIGHT_WRITABLE == 0 {
            return Err(Status::ACCESS_DENIED);
        }

        if flags & prohibited_flags != 0 {
            return Err(Status::INVALID_ARGS);
        }

        if flags & !allowed_flags != 0 {
            return Err(Status::NOT_SUPPORTED);
        }

        Ok(())
    }

    fn add_connection(
        &mut self, parent_flags: u32, flags: u32, mode: u32, server_end: ServerEnd<NodeMarker>,
    ) -> Result<(), fidl::Error> {
        // There should be no MODE_TYPE_* flags set, except for, possibly, MODE_TYPE_FILE when the
        // target is a pseudo file.
        if (mode & !MODE_PROTECTION_MASK) & !MODE_TYPE_FILE != 0 {
            let status = if (mode & !MODE_PROTECTION_MASK) & MODE_TYPE_DIRECTORY != 0 {
                Status::NOT_DIR
            } else {
                Status::INVALID_ARGS
            };
            return send_on_open_with_error(flags, server_end, status);
        }

        if let Err(status) = self.validate_flags(parent_flags, flags) {
            return send_on_open_with_error(flags, server_end, status);
        }

        match self.init_buffer(flags) {
            Ok((buffer, was_written)) => {
                let (request_stream, control_handle) =
                    ServerEnd::<FileMarker>::new(server_end.into_channel())
                        .into_stream_and_control_handle()?;

                let conn =
                    FileConnection::as_stream_future(request_stream, flags, buffer, was_written);
                self.connections.push(conn);

                if flags & OPEN_FLAG_DESCRIBE != 0 {
                    let mut info = NodeInfo::File(FileObject { event: None });
                    control_handle
                        .send_on_open_(Status::OK.into_raw(), Some(OutOfLine(&mut info)))?;
                }

                Ok(())
            }
            Err(status) => send_on_open_with_error(flags, server_end, status),
        }
    }

    fn handle_request(
        &mut self, req: FileRequest, connection: &mut FileConnection,
    ) -> Result<ConnectionState, Error> {
        match req {
            FileRequest::Clone {
                flags,
                object,
                control_handle: _,
            } => {
                self.add_connection(connection.flags, flags, 0, object)?;
            }
            FileRequest::Close { responder } => {
                self.handle_close(connection, |status| responder.send(status.into_raw()))?;
                return Ok(ConnectionState::Closed);
            }
            FileRequest::Describe { responder } => {
                let mut info = NodeInfo::File(FileObject { event: None });
                responder.send(&mut info)?;
            }
            FileRequest::Sync { responder } => {
                responder.send(ZX_ERR_NOT_SUPPORTED)?;
            }
            FileRequest::GetAttr { responder } => {
                let mut attrs = NodeAttributes {
                    mode: MODE_TYPE_FILE | self.protection_attributes,
                    id: INO_UNKNOWN,
                    content_size: 0,
                    storage_size: 0,
                    link_count: 1,
                    creation_time: 0,
                    modification_time: 0,
                };
                responder.send(ZX_OK, &mut attrs)?;
            }
            FileRequest::SetAttr {
                flags: _,
                attributes: _,
                responder,
            } => {
                // According to zircon/system/fidl/fuchsia-io/io.fidl the only flag that might be
                // modified through this call is OPEN_FLAG_APPEND, and it is not supported by the
                // PseudoFileImpl.
                responder.send(ZX_ERR_NOT_SUPPORTED)?;
            }
            FileRequest::Ioctl {
                opcode: _,
                max_out: _,
                handles: _,
                in_: _,
                responder,
            } => {
                responder.send(ZX_ERR_NOT_SUPPORTED, &mut iter::empty(), &mut iter::empty())?;
            }
            FileRequest::Read { count, responder } => {
                let actual =
                    self.handle_read(connection, connection.seek, count, |status, content| {
                        responder.send(status.into_raw(), content)
                    })?;
                connection.seek += actual;
            }
            FileRequest::ReadAt {
                offset,
                count,
                responder,
            } => {
                self.handle_read(connection, offset, count, |status, content| {
                    responder.send(status.into_raw(), content)
                })?;
            }
            FileRequest::Write { data, responder } => {
                let actual =
                    self.handle_write(connection, connection.seek, data, |status, actual| {
                        responder.send(status.into_raw(), actual)
                    })?;
                connection.seek += actual;
            }
            FileRequest::WriteAt {
                offset,
                data,
                responder,
            } => {
                self.handle_write(connection, offset, data, |status, actual| {
                    // Seems like our API is not really designed for 128 bit machines. If data
                    // contains more than 16EB, we may not be returning the correct number here.
                    responder.send(status.into_raw(), actual as u64)
                })?;
            }
            FileRequest::Seek {
                offset,
                start,
                responder,
            } => {
                self.handle_seek(connection, offset, start, |status, offset| {
                    responder.send(status.into_raw(), offset)
                })?;
            }
            FileRequest::Truncate { length, responder } => {
                self.handle_truncate(connection, length, |status| {
                    responder.send(status.into_raw())
                })?;
            }
            FileRequest::GetFlags { responder } => {
                responder.send(ZX_OK, connection.flags)?;
            }
            FileRequest::SetFlags {
                flags: _,
                responder,
            } => {
                // TODO: Support OPEN_FLAG_APPEND?  It is the only flag that is allowed to be set
                // via this call according to the io.fidl.  It would be nice to have that
                // explicitly encoded in the API instead, I guess.
                responder.send(ZX_ERR_NOT_SUPPORTED)?;
            }
            FileRequest::GetBuffer {
                flags: _,
                responder,
            } => {
                // There is no backing VMO.
                responder.send(ZX_OK, None)?;
            }
        }
        Ok(ConnectionState::Alive)
    }

    fn init_buffer(&mut self, flags: u32) -> Result<(Vec<u8>, bool), Status> {
        // No point in calling the read handler for non-readable files.
        if flags & OPEN_RIGHT_READABLE == 0 {
            return Ok((vec![], false));
        }

        match self.on_read {
            None => Ok((vec![], false)),
            Some(ref mut on_read) => {
                // No point in calling the read hander, if we want to erase all of the content
                // right away, but we need to remember the content was overwritten.
                if flags & OPEN_FLAG_TRUNCATE != 0 {
                    Ok((vec![], true))
                } else {
                    let buffer = on_read()?;
                    Ok((buffer, false))
                }
            }
        }
    }

    fn handle_read<R>(
        &mut self, connection: &FileConnection, offset: u64, mut count: u64, responder: R,
    ) -> Result<u64, fidl::Error>
    where
        R: FnOnce(Status, &mut ExactSizeIterator<Item = u8>) -> Result<(), fidl::Error>,
    {
        if connection.flags & OPEN_RIGHT_READABLE == 0 {
            responder(Status::ACCESS_DENIED, &mut iter::empty())?;
            return Ok(0);
        }

        match self.on_read {
            None => {
                responder(Status::NOT_SUPPORTED, &mut iter::empty())?;
                Ok(0)
            }
            Some(_) => {
                assert_eq_size!(usize, u64);

                let len = connection.buffer.len() as u64;

                if offset >= len {
                    responder(Status::OUT_OF_RANGE, &mut iter::empty())?;
                    return Ok(0);
                }

                count = core::cmp::min(count, len - offset);

                let from = offset as usize;
                let to = (offset + count) as usize;
                let mut content = connection.buffer[from..to].iter().cloned();
                responder(Status::OK, &mut content)?;
                Ok(count)
            }
        }
    }

    // Strictly speaking, we do not need to use a callback here, but we do need it in the
    // on_read() case above, so, for consistency, on_write() has the same interface.
    // TODO: Do I need to return the number of bytes written?
    fn handle_write<R>(
        &mut self, connection: &mut FileConnection, offset: u64, content: Vec<u8>, responder: R,
    ) -> Result<u64, fidl::Error>
    where
        R: FnOnce(Status, u64) -> Result<(), fidl::Error>,
    {
        if connection.flags & OPEN_RIGHT_WRITABLE == 0 {
            responder(Status::ACCESS_DENIED, 0)?;
            return Ok(0);
        }

        assert_eq_size!(usize, u64);
        let effective_capacity = core::cmp::max(connection.buffer.len() as u64, self.capacity);

        match self.on_write {
            None => {
                responder(Status::NOT_SUPPORTED, 0)?;
                Ok(0)
            }
            Some(_) if offset >= effective_capacity => {
                responder(Status::OUT_OF_RANGE, 0)?;
                Ok(0)
            }
            Some(_) => {
                assert_eq_size!(usize, u64);

                let actual = core::cmp::min(effective_capacity - offset, content.len() as u64);

                let buffer = &mut connection.buffer;

                if buffer.len() as u64 <= offset + actual {
                    buffer.resize((offset + actual) as usize, 0);
                }

                let from = offset as usize;
                let to = (offset + actual) as usize;
                let mut target = &mut buffer[from..to];
                let source = &content[0..actual as usize];
                target.write_all(source).unwrap();

                connection.was_written = true;

                responder(Status::OK, actual)?;
                Ok(actual)
            }
        }
    }

    fn handle_seek<R>(
        &mut self, connection: &mut FileConnection, offset: i64, start: SeekOrigin, responder: R,
    ) -> Result<(), fidl::Error>
    where
        R: FnOnce(Status, u64) -> Result<(), fidl::Error>,
    {
        let new_seek = match start {
            SeekOrigin::Start => offset as i128,

            SeekOrigin::Current => {
                assert_eq_size!(usize, i64);
                connection.seek as i128 + offset as i128
            }

            SeekOrigin::End => {
                assert_eq_size!(usize, i64, u64);
                connection.buffer.len() as i128 + offset as i128
            }
        };

        let effective_capacity =
            core::cmp::max(connection.buffer.len() as i128, self.capacity as i128);
        if new_seek < 0 || new_seek >= effective_capacity {
            responder(Status::OUT_OF_RANGE, connection.seek)?;
            return Ok(());
        }
        let new_seek = new_seek as u64;

        connection.seek = new_seek;
        responder(Status::OK, new_seek)
    }

    fn handle_truncate<R>(
        &mut self, connection: &mut FileConnection, length: u64, responder: R,
    ) -> Result<(), fidl::Error>
    where
        R: FnOnce(Status) -> Result<(), fidl::Error>,
    {
        if connection.flags & OPEN_RIGHT_WRITABLE == 0 {
            return responder(Status::ACCESS_DENIED);
        }

        let effective_capacity = core::cmp::max(connection.buffer.len() as u64, self.capacity);

        match self.on_write {
            None => responder(Status::NOT_SUPPORTED),
            Some(_) if length > effective_capacity => responder(Status::OUT_OF_RANGE),
            Some(_) => {
                assert_eq_size!(usize, u64);

                connection.buffer.resize(length as usize, 0);

                // We are not supposed to touch the seek position during truncation, but the
                // effective_capacity may be smaller now - in which case we do need to move the
                // seek position.
                let new_effective_capacity = core::cmp::max(length, self.capacity);
                connection.seek = core::cmp::min(connection.seek, new_effective_capacity);

                responder(Status::OK)
            }
        }
    }

    fn handle_close<R>(
        &mut self, connection: &mut FileConnection, responder: R,
    ) -> Result<(), fidl::Error>
    where
        R: FnOnce(Status) -> Result<(), fidl::Error>,
    {
        if !connection.was_written {
            return responder(Status::OK);
        }

        match self.on_write {
            None => responder(Status::OK),
            Some(ref mut on_write) => {
                match on_write(mem::replace(&mut connection.buffer, vec![])) {
                    Ok(()) => responder(Status::OK),
                    Err(status) => responder(status),
                }
            }
        }
    }
}

impl<OnRead, OnWrite> DirectoryEntry for PseudoFileImpl<OnRead, OnWrite>
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    fn open(
        &mut self, flags: u32, mode: u32, path: &mut Iterator<Item = &str>,
        server_end: ServerEnd<NodeMarker>,
    ) -> Result<(), fidl::Error> {
        if let Some(_) = path.next() {
            return send_on_open_with_error(flags, server_end, Status::NOT_DIR);
        }

        self.add_connection(!0, flags, mode, server_end)
    }

    fn entry_info(&self) -> EntryInfo {
        EntryInfo::new(INO_UNKNOWN, DIRENT_TYPE_FILE)
    }
}

impl<OnRead, OnWrite> PseudoFile for PseudoFileImpl<OnRead, OnWrite>
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
}

impl<OnRead, OnWrite> Unpin for PseudoFileImpl<OnRead, OnWrite>
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
}

impl<OnRead, OnWrite> FusedFuture for PseudoFileImpl<OnRead, OnWrite>
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    fn is_terminated(&self) -> bool {
        // The `PseudoFileImpl` never completes, but once there are no
        // more connections, it is blocked until more connections are
        // added. If the object currently polling a `PseudoFile` with
        // an empty set of connections is blocked on the `PseudoFile`
        // completing, it will never terminate.
        self.connections.len() == 0
    }
}

impl<OnRead, OnWrite> Future for PseudoFileImpl<OnRead, OnWrite>
where
    OnRead: FnMut() -> Result<Vec<u8>, Status>,
    OnWrite: FnMut(Vec<u8>) -> Result<(), Status>,
{
    type Output = Void;

    fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
        loop {
            match self.connections.poll_next_unpin(lw) {
                Poll::Ready(Some((maybe_request, mut connection))) => {
                    if let Some(Ok(request)) = maybe_request {
                        match self.handle_request(request, &mut connection) {
                            Ok(ConnectionState::Alive) => {
                                self.connections.push(connection.into_future())
                            }
                            Ok(ConnectionState::Closed) => (),
                            // An error occured while processing a request.  We will just close the
                            // connection, effectively closing the underlying channel in the
                            // desctructor.
                            _ => (),
                        }
                    }
                    // Similarly to the error that occures while handing a FIDL request, any
                    // connection level errors cause the connection to be closed.
                }
                // Even when we have no connections any more we still report Pending state, as we
                // may get more connections open in the future.
                Poll::Ready(None) | Poll::Pending => return Poll::Pending,
            }
        }
    }
}

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

    use {
        fidl::endpoints::{create_proxy, ServerEnd},
        fidl_fuchsia_io::{FileEvent, FileMarker, FileProxy, INO_UNKNOWN, MODE_TYPE_FILE},
        fuchsia_async as fasync,
        fuchsia_zircon::sys::{ZX_ERR_ACCESS_DENIED, ZX_ERR_SHOULD_WAIT},
        futures::channel::{mpsc, oneshot},
        futures::{future::LocalFutureObj, select, Future, FutureExt, SinkExt},
        libc::{S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR},
        pin_utils::pin_mut,
        std::cell::RefCell,
    };

    fn run_server_client<GetClientRes>(
        flags: u32, server: impl PseudoFile, get_client: impl FnOnce(FileProxy) -> GetClientRes,
    ) where
        GetClientRes: Future<Output = ()>,
    {
        run_server_client_with_mode(flags, 0, server, get_client)
    }

    fn run_server_client_with_mode<GetClientRes>(
        flags: u32, mode: u32, mut server: impl PseudoFile,
        get_client: impl FnOnce(FileProxy) -> GetClientRes,
    ) where
        GetClientRes: Future<Output = ()>,
    {
        let mut exec = fasync::Executor::new().expect("Executor creation failed");

        let (client_proxy, server_end) =
            create_proxy::<FileMarker>().expect("Failed to create connection endpoints");

        server
            .open(
                flags,
                mode,
                &mut iter::empty(),
                ServerEnd::new(server_end.into_channel()),
            )
            .expect("open() failed");

        let client = get_client(client_proxy);

        let future = server.join(client);
        // TODO: How to limit the execution time?  run_until_stalled() does not trigger timers, so
        // I can not do this:
        //
        //   let timeout = 300.millis();
        //   let future = future.on_timeout(
        //       timeout.after_now(),
        //       || panic!("Test did not finish in {}ms", timeout.millis()));

        // As our clients are async generators, we need to pin this future explicitly.
        // All async generators are !Unpin by default.
        pin_mut!(future);
        exec.run_until_stalled(&mut future);
    }

    fn run_server_client_with_open_requests_channel_and_executor<GetClientRes>(
        mut exec: fasync::Executor, mut server: impl PseudoFile,
        get_client: impl FnOnce(mpsc::Sender<(u32, u32, ServerEnd<FileMarker>)>) -> GetClientRes,
        executor: impl FnOnce(&mut FnMut() -> Poll<((), ())>),
    ) where
        GetClientRes: Future<Output = ()>,
    {
        let (open_requests_tx, open_requests_rx) =
            mpsc::channel::<(u32, u32, ServerEnd<FileMarker>)>(0);

        let server_wrapper = async move {
            let mut open_requests_rx = open_requests_rx.fuse();
            loop {
                select! {
                    _ = server => panic!("file should never complete"),
                    open_req = open_requests_rx.next() => {
                        if let Some((flags, mode, server_end)) = open_req {
                            server
                                .open(flags, mode, &mut iter::empty(),
                                      ServerEnd::new(server_end.into_channel()))
                                .expect("open() failed");
                        }
                    },
                    complete => return,
                }
            }
        };

        let client = get_client(open_requests_tx);

        let future = server_wrapper.join(client);

        // As our clients are async generators, we need to pin this future explicitly.
        // All async generators are !Unpin by default.
        pin_mut!(future);
        let mut obj = LocalFutureObj::new(future);
        executor(&mut || exec.run_until_stalled(&mut obj));
    }

    fn run_server_client_with_open_requests_channel<GetClientRes>(
        server: impl PseudoFile,
        get_client: impl FnOnce(mpsc::Sender<(u32, u32, ServerEnd<FileMarker>)>) -> GetClientRes,
    ) where
        GetClientRes: Future<Output = ()>,
    {
        let exec = fasync::Executor::new().expect("Executor creation failed");

        run_server_client_with_open_requests_channel_and_executor(
            exec,
            server,
            get_client,
            |run_until_stalled| {
                run_until_stalled();
            },
        );
    }

    #[test]
    fn read_only_read() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| Ok(b"Read only test".to_vec())),
            async move |proxy| {
                assert_read!(proxy, "Read only test");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn read_only_read_no_status() {
        run_server_client_with_open_requests_channel(
            read_only(|| Ok(b"Read only test".to_vec())),
            async move |mut open_sender| {
                let (proxy, server_end) =
                    create_proxy::<FileMarker>().expect("Failed to create connection endpoints");

                let flags = OPEN_RIGHT_READABLE;
                await!(open_sender.send((flags, 0, server_end))).unwrap();
                assert_no_event!(proxy);
            },
        );
    }

    #[test]
    fn read_only_read_with_describe() {
        run_server_client_with_open_requests_channel(
            read_only(|| Ok(b"Read only test".to_vec())),
            async move |mut open_sender| {
                let (proxy, server_end) =
                    create_proxy::<FileMarker>().expect("Failed to create connection endpoints");

                let flags = OPEN_RIGHT_READABLE | OPEN_FLAG_DESCRIBE;
                await!(open_sender.send((flags, 0, server_end))).unwrap();
                assert_event!(proxy, FileEvent::OnOpen_ { s, info }, {
                    assert_eq!(s, ZX_OK);
                    assert_eq!(
                        info,
                        Some(Box::new(NodeInfo::File(FileObject { event: None })))
                    );
                });
            },
        );
    }

    #[test]
    fn read_only_str_read() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only_str(|| Ok(String::from("Read only str test"))),
            async move |proxy| {
                assert_read!(proxy, "Read only str test");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn write_only_write() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(100, |content| {
                assert_eq!(&*content, b"Write only test");
                Ok(())
            }),
            async move |proxy| {
                assert_write!(proxy, "Write only test");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn write_only_str_write() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only_str(100, |content| {
                assert_eq!(&*content, "Write only test");
                Ok(())
            }),
            async move |proxy| {
                assert_write!(proxy, "Write only test");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn read_write_read_and_write() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Hello".to_vec()),
                100,
                |content| {
                    assert_eq!(*&content, b"Hello, world!");
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_read!(proxy, "Hello");
                assert_write!(proxy, ", world!");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn read_write_str_read_and_write() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write_str(
                || Ok("Hello".to_string()),
                100,
                |content| {
                    assert_eq!(*&content, "Hello, world!");
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_read!(proxy, "Hello");
                assert_write!(proxy, ", world!");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn read_twice() {
        let mut read_attempt = 0;

        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| {
                read_attempt += 1;
                match read_attempt {
                    1 => Ok(b"State one".to_vec()),
                    _ => panic!("Third read() call."),
                }
            }),
            async move |proxy| {
                assert_read!(proxy, "State one");
                assert_seek!(proxy, 0, Start);
                assert_read!(proxy, "State one");
                assert_close!(proxy);
            },
        );

        assert_eq!(read_attempt, 1);
    }

    #[test]
    fn write_twice() {
        let mut write_attempt = 0;

        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(100, |content| {
                write_attempt += 1;
                match write_attempt {
                    1 => {
                        assert_eq!(&*content, b"Write one and two");
                        Ok(())
                    }
                    _ => panic!("Second write() call.  Content: '{:?}'", content),
                }
            }),
            async move |proxy| {
                assert_write!(proxy, "Write one");
                assert_write!(proxy, " and two");
                assert_close!(proxy);
            },
        );

        assert_eq!(write_attempt, 1);
    }

    #[test]
    fn read_error() {
        let mut read_attempt = 0;

        let flags = OPEN_RIGHT_READABLE | OPEN_FLAG_DESCRIBE;
        let server = read_only(|| {
            read_attempt += 1;
            match read_attempt {
                1 => Err(Status::SHOULD_WAIT),
                2 => Ok(b"Have value".to_vec()),
                _ => panic!("Third call to read()."),
            }
        });

        run_server_client_with_open_requests_channel(server, async move |mut open_sender| {
            {
                let (proxy, server_end) =
                    create_proxy::<FileMarker>().expect("Failed to create connection endpoints");

                await!(open_sender.send((flags, 0, server_end))).unwrap();
                assert_event!(proxy, FileEvent::OnOpen_ { s, info }, {
                    assert_eq!(s, ZX_ERR_SHOULD_WAIT);
                    assert_eq!(info, None);
                });
            }

            {
                let (proxy, server_end) =
                    create_proxy::<FileMarker>().expect("Failed to create connection endpoints");

                await!(open_sender.send((flags, 0, server_end))).unwrap();
                assert_event!(proxy, FileEvent::OnOpen_ { s, info }, {
                    assert_eq!(s, ZX_OK);
                    assert_eq!(
                        info,
                        Some(Box::new(NodeInfo::File(FileObject { event: None })))
                    );
                });

                assert_read!(proxy, "Have value");
                assert_close!(proxy);
            }
        });
    }

    #[test]
    fn read_write_no_write_flag() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_write(
                || Ok(b"Can read".to_vec()),
                100,
                |_content| {
                    panic!("File was not opened as writable");
                },
            ),
            async move |proxy| {
                assert_read!(proxy, "Can read");
                assert_write_err!(proxy, "Can write", Status::ACCESS_DENIED);
                assert_write_at_err!(proxy, 0, "Can write", Status::ACCESS_DENIED);
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn read_write_no_read_flag() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            read_write(
                || {
                    panic!("File was not opened as readable");
                },
                100,
                |content| {
                    assert_eq!(*&content, b"Can write");
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_read_err!(proxy, Status::ACCESS_DENIED);
                assert_read_at_err!(proxy, 0, Status::ACCESS_DENIED);
                assert_write!(proxy, "Can write");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    /// When the read handler returns a value that is larger then the specified capacity of the
    /// file, write handler will receive it as is, uncut.  This behaviour is specified in the
    /// description of [`PseudoFileImpl::capacity`].
    fn read_returns_more_than_capacity() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Read handler may return more than capacity".to_vec()),
                10,
                |content| {
                    assert_eq!(
                        content,
                        b"Write then could write beyond max capacity".to_vec()
                    );
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_read!(proxy, "Read");
                assert_seek!(proxy, 0, Start);
                // Need to write something, otherwise write handler will not be called.
                // " capacity" is a leftover from what read handler has returned.
                assert_write!(proxy, "Write then could write beyond max");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn write_error() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(100, |content| {
                assert_eq!(*&content, b"Wrong format");
                Err(Status::INVALID_ARGS)
            }),
            async move |proxy| {
                assert_write!(proxy, "Wrong");
                assert_write!(proxy, " format");
                assert_close_err!(proxy, Status::INVALID_ARGS);
            },
        );
    }

    #[test]
    fn open_truncate() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE | OPEN_FLAG_TRUNCATE,
            read_write(
                || panic!("OPEN_FLAG_TRUNCATE means read() is not called."),
                100,
                |content| {
                    assert_eq!(*&content, b"File content");
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_write!(proxy, "File content");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn read_at_0() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| Ok(b"Whole file content".to_vec())),
            async move |proxy| {
                assert_read_at!(proxy, 0, "Whole file content");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn read_at_overlapping() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| Ok(b"Content of the file".to_vec())),
            //                0         1
            //                0123456789012345678
            async move |proxy| {
                assert_read_at!(proxy, 3, "tent of the");
                assert_read_at!(proxy, 11, "the file");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn read_mixed_with_read_at() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| Ok(b"Content of the file".to_vec())),
            //                0         1
            //                0123456789012345678
            async move |proxy| {
                assert_read!(proxy, "Content");
                assert_read_at!(proxy, 3, "tent of the");
                assert_read!(proxy, " of the ");
                assert_read_at!(proxy, 11, "the file");
                assert_read!(proxy, "file");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn write_at_0() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(100, |content| {
                assert_eq!(*&content, b"File content");
                Ok(())
            }),
            async move |proxy| {
                assert_write_at!(proxy, 0, "File content");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn write_at_overlapping() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(100, |content| {
                assert_eq!(*&content, b"Whole file content");
                //                      0         1
                //                      012345678901234567
                Ok(())
            }),
            async move |proxy| {
                assert_write_at!(proxy, 8, "le content");
                assert_write_at!(proxy, 6, "file");
                assert_write_at!(proxy, 0, "Whole file");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn write_mixed_with_write_at() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(100, |content| {
                assert_eq!(*&content, b"Whole file content");
                //                      0         1
                //                      012345678901234567
                Ok(())
            }),
            async move |proxy| {
                assert_write!(proxy, "whole");
                assert_write_at!(proxy, 0, "Who");
                assert_write!(proxy, " 1234 ");
                assert_write_at!(proxy, 6, "file");
                assert_write!(proxy, "content");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn seek_read_write() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Initial".to_vec()),
                100,
                |content| {
                    assert_eq!(*&content, b"Final content");
                    //                      0         1
                    //                      0123456789012
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_read!(proxy, "Init");
                assert_write!(proxy, "l con");
                // buffer: "Initl con"
                assert_seek!(proxy, 0, Start);
                assert_write!(proxy, "Fina");
                // buffer: "Final con"
                assert_seek!(proxy, 0, End, 9);
                assert_write!(proxy, "tent");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn seek_valid_positions() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| Ok(b"Long file content".to_vec())),
            //                0         1
            //                01234567890123456
            async move |proxy| {
                assert_seek!(proxy, 5, Start);
                assert_read!(proxy, "file");
                assert_seek!(proxy, 1, Current, 10);
                assert_read!(proxy, "content");
                assert_seek!(proxy, -12, End, 5);
                assert_read!(proxy, "file content");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn seek_valid_after_size_before_capacity() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Content".to_vec()),
                //      0123456
                100,
                |content| {
                    assert_eq!(*&content, b"Content extended further");
                    //                      0         1         2
                    //                      012345678901234567890123
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_seek!(proxy, 7, Start);
                assert_read_err!(proxy, Status::OUT_OF_RANGE);
                assert_write!(proxy, " ext");
                //      "Content ext"));
                assert_seek!(proxy, 3, Current, 14);
                assert_write!(proxy, "ed");
                //      "Content ext000ed"));
                assert_seek!(proxy, 4, End, 20);
                assert_write!(proxy, "ther");
                //      "Content ext000ed0000ther"));
                //       0         1         2
                //       012345678901234567890123
                assert_seek!(proxy, 11, Start);
                assert_write!(proxy, "end");
                assert_seek!(proxy, 16, Start);
                assert_write!(proxy, " fur");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn seek_invalid_before_0() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| Ok(b"Seek position is unaffected".to_vec())),
            //                0         1         2
            //                012345678901234567890123456
            async move |proxy| {
                assert_seek_err!(proxy, -10, Current, Status::OUT_OF_RANGE, 0);
                assert_read!(proxy, "Seek");
                assert_seek_err!(proxy, -10, Current, Status::OUT_OF_RANGE, 4);
                assert_read!(proxy, " position");
                assert_seek_err!(proxy, -100, End, Status::OUT_OF_RANGE, 13);
                assert_read!(proxy, " is unaffected");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn seek_invalid_after_capacity() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Content".to_vec()),
                //      0123456
                10,
                |_content| panic!("No writes should have happened"),
            ),
            async move |proxy| {
                assert_seek!(proxy, 8, Start);
                assert_seek_err!(proxy, 12, Start, Status::OUT_OF_RANGE, 8);
                assert_seek_err!(proxy, 3, Current, Status::OUT_OF_RANGE, 8);
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn seek_after_truncate() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Content".to_vec()),
                //      0123456
                100,
                |content| {
                    assert_eq!(*&content, b"Content\0\0\0end");
                    //                      0            1
                    //                      01234567 8 9 012
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_truncate!(proxy, 12);
                assert_seek!(proxy, 10, Start);
                assert_write!(proxy, "end");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    /// Make sure that even if the file content is larger than the capacity, seek does not allow to
    /// go beyond the maximum of the capacity and length.
    fn seek_beyond_capacity_in_large_file() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Long content".to_vec()),
                //      0         1
                //      012345678901
                8,
                |_content| panic!("No writes should have happened"),
            ),
            async move |proxy| {
                assert_seek!(proxy, 10, Start);
                assert_seek_err!(proxy, 12, Start, Status::OUT_OF_RANGE, 10);
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn truncate_to_0() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Content".to_vec()),
                //      0123456
                100,
                |content| {
                    assert_eq!(*&content, b"Replaced");
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_read!(proxy, "Content");
                assert_truncate!(proxy, 0);
                // truncate should not change the seek position.
                assert_seek!(proxy, 0, Current, 7);
                assert_seek!(proxy, 0, Start);
                assert_write!(proxy, "Replaced");
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn write_then_truncate() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(100, |content| {
                assert_eq!(*&content, b"Replaced");
                Ok(())
            }),
            async move |proxy| {
                assert_write!(proxy, "Replaced content");
                assert_truncate!(proxy, 8);
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn truncate_beyond_capacity() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(10, |_content| panic!("No writes should have happened")),
            async move |proxy| {
                assert_truncate_err!(proxy, 20, Status::OUT_OF_RANGE);
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn truncate_read_only_file() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| Ok(b"Read-only content".to_vec())),
            async move |proxy| {
                assert_truncate_err!(proxy, 10, Status::ACCESS_DENIED);
                assert_close!(proxy);
            },
        );
    }

    #[test]
    /// Make sure that when the read hander has returned a buffer that is larger than the capacity,
    /// we can cut it down to a something that is still larger then the capacity.  But we can not
    /// undo that cut.
    fn truncate_large_file_beyond_capacity() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Content is very long".to_vec()),
                //      0         1
                //      01234567890123456789
                10,
                |content| {
                    assert_eq!(*&content, b"Content is very");
                    //                      0         1
                    //                      012345678901234
                    Ok(())
                },
            ),
            async move |proxy| {
                assert_read!(proxy, "Content");
                assert_truncate_err!(proxy, 40, Status::OUT_OF_RANGE);
                assert_truncate!(proxy, 16);
                assert_truncate!(proxy, 14);
                assert_truncate_err!(proxy, 16, Status::OUT_OF_RANGE);
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn clone_reduce_access() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Initial content".to_vec()),
                100,
                |content| {
                    assert_eq!(*&content, b"As updated");
                    Ok(())
                },
            ),
            async move |first_proxy| {
                assert_read!(first_proxy, "Initial content");
                assert_truncate!(first_proxy, 0);
                assert_seek!(first_proxy, 0, Start);
                assert_write!(first_proxy, "As updated");

                let (second_proxy, second_server_end) = create_proxy::<FileMarker>().unwrap();

                first_proxy
                    .clone(
                        OPEN_RIGHT_READABLE | OPEN_FLAG_DESCRIBE,
                        // second_server_end is a ServerEnd<FileMarker> while we need a
                        // ServerEnd<NodeMarker> :(
                        ServerEnd::new(second_server_end.into_channel()),
                    )
                    .unwrap();

                let event_stream = second_proxy.take_event_stream();
                match await!(event_stream.into_future()) {
                    (Some(Ok(FileEvent::OnOpen_ { s, info })), _) => {
                        assert_eq!(s, ZX_OK);
                        assert!(info.is_some());
                        assert_eq!(*info.unwrap(), NodeInfo::File(FileObject { event: None }));
                    }
                    (unexpected, _) => {
                        panic!("Unexpected event: {:?}", unexpected);
                    }
                }

                assert_read!(second_proxy, "Initial content");
                assert_truncate_err!(second_proxy, 0, Status::ACCESS_DENIED);
                assert_write_err!(second_proxy, "As updated", Status::ACCESS_DENIED);

                assert_close!(first_proxy);
                assert_close!(second_proxy);
            },
        );
    }

    #[test]
    fn get_attr_read_only() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only(|| Ok(b"Content".to_vec())),
            async move |proxy| {
                assert_get_attr!(
                    proxy,
                    NodeAttributes {
                        mode: MODE_TYPE_FILE | S_IRUSR,
                        id: INO_UNKNOWN,
                        content_size: 0,
                        storage_size: 0,
                        link_count: 1,
                        creation_time: 0,
                        modification_time: 0,
                    }
                );
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn get_attr_write_only() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only(10, |_content| panic!("No changes")),
            async move |proxy| {
                assert_get_attr!(
                    proxy,
                    NodeAttributes {
                        mode: MODE_TYPE_FILE | S_IWUSR,
                        id: INO_UNKNOWN,
                        content_size: 0,
                        storage_size: 0,
                        link_count: 1,
                        creation_time: 0,
                        modification_time: 0,
                    }
                );
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn get_attr_read_write() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write(
                || Ok(b"Content".to_vec()),
                10,
                |_content| panic!("No changes"),
            ),
            async move |proxy| {
                assert_get_attr!(
                    proxy,
                    NodeAttributes {
                        mode: MODE_TYPE_FILE | S_IWUSR | S_IRUSR,
                        id: INO_UNKNOWN,
                        content_size: 0,
                        storage_size: 0,
                        link_count: 1,
                        creation_time: 0,
                        modification_time: 0,
                    }
                );
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn get_attr_read_only_attr() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_only_attr(
                || Ok(b"Content".to_vec()),
                S_IXOTH | S_IROTH | S_IXGRP | S_IRGRP | S_IXUSR | S_IRUSR,
            ),
            async move |proxy| {
                assert_get_attr!(
                    proxy,
                    NodeAttributes {
                        mode: MODE_TYPE_FILE
                            | (S_IXOTH | S_IROTH | S_IXGRP | S_IRGRP | S_IXUSR | S_IRUSR),
                        id: INO_UNKNOWN,
                        content_size: 0,
                        storage_size: 0,
                        link_count: 1,
                        creation_time: 0,
                        modification_time: 0,
                    }
                );
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn get_attr_write_only_attr() {
        run_server_client(
            OPEN_RIGHT_WRITABLE,
            write_only_attr(
                10,
                |_content| panic!("No changes"),
                S_IWOTH | S_IWGRP | S_IWUSR,
            ),
            async move |proxy| {
                assert_get_attr!(
                    proxy,
                    NodeAttributes {
                        mode: MODE_TYPE_FILE | S_IWOTH | S_IWGRP | S_IWUSR,
                        id: INO_UNKNOWN,
                        content_size: 0,
                        storage_size: 0,
                        link_count: 1,
                        creation_time: 0,
                        modification_time: 0,
                    }
                );
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn get_attr_read_write_attr() {
        run_server_client(
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            read_write_attr(
                || Ok(b"Content".to_vec()),
                10,
                |_content| panic!("No changes"),
                S_IXOTH
                    | S_IROTH
                    | S_IWOTH
                    | S_IXGRP
                    | S_IRGRP
                    | S_IWGRP
                    | S_IXUSR
                    | S_IRUSR
                    | S_IWUSR,
            ),
            async move |proxy| {
                assert_get_attr!(
                    proxy,
                    NodeAttributes {
                        mode: MODE_TYPE_FILE
                            | (S_IXOTH
                                | S_IROTH
                                | S_IWOTH
                                | S_IXGRP
                                | S_IRGRP
                                | S_IWGRP
                                | S_IXUSR
                                | S_IRUSR
                                | S_IWUSR),
                        id: INO_UNKNOWN,
                        content_size: 0,
                        storage_size: 0,
                        link_count: 1,
                        creation_time: 0,
                        modification_time: 0,
                    }
                );
                assert_close!(proxy);
            },
        );
    }

    #[test]
    fn clone_cannot_increase_access() {
        run_server_client(
            OPEN_RIGHT_READABLE,
            read_write(
                || Ok(b"Initial content".to_vec()),
                100,
                |_content| {
                    panic!("Clone should not be able to write.");
                },
            ),
            async move |first_proxy| {
                assert_read!(first_proxy, "Initial content");
                assert_write_err!(first_proxy, "Write attempt", Status::ACCESS_DENIED);

                let (second_proxy, second_server_end) = create_proxy::<FileMarker>().unwrap();

                first_proxy
                    .clone(
                        OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE | OPEN_FLAG_DESCRIBE,
                        // TODO second_server_end is ServerEnd<FileMarker> but we need
                        // ServerEnd<NodeMarker> :(  Should we add an implementation of From<> to
                        // the FIDL compiler output?
                        ServerEnd::new(second_server_end.into_channel()),
                    )
                    .unwrap();

                let event_stream = second_proxy.take_event_stream();
                match await!(event_stream.into_future()) {
                    (Some(Ok(FileEvent::OnOpen_ { s, info })), _) => {
                        assert_eq!(s, ZX_ERR_ACCESS_DENIED);
                        assert_eq!(info, None);
                    }
                    (unexpected, _) => {
                        panic!("Unexpected event: {:?}", unexpected);
                    }
                }

                assert_read_fidl_err!(second_proxy, fidl::Error::ClientWrite(Status::PEER_CLOSED));
                assert_write_fidl_err!(
                    second_proxy,
                    "Write attempt",
                    fidl::Error::ClientWrite(Status::PEER_CLOSED)
                );

                assert_close!(first_proxy);
            },
        );
    }

    #[test]
    fn mock_directory_with_one_file_and_two_connections() {
        // If futures::join would provide a way to "unpack" an incomplete (or complete) Join
        // future, this test could have been written a bit easier.  Without the unpack
        // functionality as soon as the pseudo_file is combined the client into a joined future,
        // there is no way to add new connections to it.  So I need to have a select! loop.  I do
        // not see a reason why Join should not allow to unpack, except that this functionality is
        // probably only useful in tests or some other very special situations, so it was probably
        // just not implemented yet.
        //
        // On the up side, this test implementation is half way of what a pseudo directory will
        // (maybe already does) look like - may catch more relevant bugs.
        //
        // I was thinking about something like this:
        //
        // let future = server.join(first_client);
        // pin_mut!(future);
        // if let Poll::Ready((Err(e), ())) = exec.run_until_stalled(&mut future) {
        //     panic!("Server failed: {:?}", e);
        // }
        //
        // let (server, first_client) = match future.unpack() {
        //     Join(MaybeDone::Future(server), MaybeDone::Future(first_client))
        //         => (server, first_client),
        //     Join(MaybeDone::Done(res), _) => panic!("Server has stopped: {:?}", res),
        //     Join(_, MaybeDone::Done(())) => panic!("First client has stopped"),
        //     _ => panic!("Unepxected join state"),
        // };
        //
        // let (second_client, second_client_server_end) = ...
        //
        // server.open(flags, 0, &mut iter::empty(), second_client_server_end).unwrap();
        //
        // let future = server.join3(first_client);
        // pin_mut!(future);
        // if let Poll::Ready((Err(e), (), ())) = exec.run_until_stalled(&mut future) {
        //     panic!("Server failed: {:?}", e);
        // }

        let exec = fasync::Executor::new().expect("Executor creation failed");

        let create_client = move |expected_content: &'static str| {
            let (proxy, server_end) =
                create_proxy::<FileMarker>().expect("Failed to create connection endpoints");

            let (start_sender, start_receiver) = oneshot::channel::<()>();
            let (read_and_close_sender, read_and_close_receiver) = oneshot::channel::<()>();

            (
                move |mut open_sender: mpsc::Sender<(u32, u32, ServerEnd<FileMarker>)>| {
                    async move {
                        await!(start_receiver).unwrap();

                        await!(open_sender.send((OPEN_RIGHT_READABLE, 0, server_end))).unwrap();

                        assert_read!(proxy, expected_content);

                        await!(read_and_close_receiver).unwrap();

                        assert_seek!(proxy, 0, Start);
                        assert_read!(proxy, expected_content);
                        assert_close!(proxy);
                    }
                },
                || {
                    start_sender.send(()).unwrap();
                },
                || {
                    read_and_close_sender.send(()).unwrap();
                },
            )
        };

        let read_count = RefCell::new(0);
        let (get_client1, client1_start, client1_read_and_close) = create_client("Content 1");
        let (get_client2, client2_start, client2_read_and_close) = create_client("Content 2");

        run_server_client_with_open_requests_channel_and_executor(
            exec,
            read_only_str(|| {
                let mut count = read_count.borrow_mut();
                *count += 1;
                Ok(format!("Content {}", *count))
            }),
            async move |open_sender| {
                let client1 = get_client1(open_sender.clone());
                let client2 = get_client2(open_sender.clone());

                await!(client1.join(client2));
            },
            |run_until_stalled| {
                let mut run_and_check_read_count = |expected_count, should_complete: bool| {
                    if !should_complete {
                        if let Poll::Ready(((), ())) = run_until_stalled() {
                            panic!("Future should not complete");
                        }
                    } else {
                        if let Poll::Pending = run_until_stalled() {
                            panic!("Future did not complete as expected");
                        }
                    }
                    assert_eq!(*read_count.borrow(), expected_count);
                };

                run_and_check_read_count(0, false);

                client1_start();

                run_and_check_read_count(1, false);

                client2_start();

                run_and_check_read_count(2, false);

                client1_read_and_close();

                run_and_check_read_count(2, false);

                client2_read_and_close();

                run_and_check_read_count(2, true)
            },
        );
    }
}
