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

//! Utility functions for fuchsia.io nodes.

use {
    fidl_fuchsia_io as fio, fuchsia_zircon_status as zx_status, futures::prelude::*,
    thiserror::Error,
};

/// An error encountered while opening a node
#[derive(Debug, Clone, Error)]
#[allow(missing_docs)]
pub enum OpenError {
    #[error("while making a fidl proxy: {0}")]
    CreateProxy(#[source] fidl::Error),

    #[error("while opening from namespace: {0}")]
    Namespace(#[source] zx_status::Status),

    #[error("while sending open request: {0}")]
    SendOpenRequest(#[source] fidl::Error),

    #[error("node event stream closed prematurely")]
    OnOpenEventStreamClosed,

    #[error("while reading OnOpen event: {0}")]
    OnOpenDecode(#[source] fidl::Error),

    #[error("open failed with status: {0}")]
    OpenError(#[source] zx_status::Status),

    #[error("remote responded with success but provided no node info")]
    MissingOnOpenInfo,

    #[error("expected node to be a {expected:?}, but got a {actual:?}")]
    UnexpectedNodeKind { expected: Kind, actual: Kind },
}

impl OpenError {
    /// Returns true if the open failed because the node was not found.
    pub fn is_not_found_error(&self) -> bool {
        matches!(
            self,
            OpenError::OpenError(zx_status::Status::NOT_FOUND)
                | OpenError::Namespace(zx_status::Status::NOT_FOUND)
        )
    }
}

/// An error encountered while cloning a node
#[derive(Debug, Clone, Error)]
#[allow(missing_docs)]
pub enum CloneError {
    #[error("while making a fidl proxy: {0}")]
    CreateProxy(#[source] fidl::Error),

    #[error("while sending clone request: {0}")]
    SendCloneRequest(#[source] fidl::Error),
}

/// An error encountered while closing a node
#[derive(Debug, Clone, Error)]
#[allow(missing_docs)]
pub enum CloseError {
    #[error("while sending close request: {0}")]
    SendCloseRequest(#[source] fidl::Error),

    #[error("close failed with status: {0}")]
    CloseError(#[source] zx_status::Status),
}

/// An error encountered while renaming a node
#[derive(Debug, Clone, Error)]
#[allow(missing_docs)]
pub enum RenameError {
    #[error("while sending rename request")]
    SendRenameRequest(#[source] fidl::Error),

    #[error("while sending get_token request")]
    SendGetTokenRequest(#[source] fidl::Error),

    #[error("rename failed with status")]
    RenameError(#[source] zx_status::Status),

    #[error("while opening subdirectory")]
    OpenError(#[from] OpenError),

    #[error("get_token failed with status")]
    GetTokenError(#[source] zx_status::Status),

    #[error("no handle from get token")]
    NoHandleError,
}

/// The type of a filesystem node
#[derive(Debug, Clone, PartialEq, Eq)]
#[allow(missing_docs)]
pub enum Kind {
    Service,
    File,
    Directory,
    Symlink,
    Unknown,
}

impl Kind {
    pub(crate) fn kind_of(info: &fio::NodeInfoDeprecated) -> Kind {
        match info {
            fio::NodeInfoDeprecated::Service(_) => Kind::Service,
            fio::NodeInfoDeprecated::File(_) => Kind::File,
            fio::NodeInfoDeprecated::Directory(_) => Kind::Directory,
            fio::NodeInfoDeprecated::Symlink(_) => Kind::Symlink,
        }
    }

    fn expect_file(info: fio::NodeInfoDeprecated) -> Result<(), Kind> {
        match info {
            fio::NodeInfoDeprecated::File(fio::FileObject { .. }) => Ok(()),
            other => Err(Kind::kind_of(&other)),
        }
    }

    fn expect_directory(info: fio::NodeInfoDeprecated) -> Result<(), Kind> {
        match info {
            fio::NodeInfoDeprecated::Directory(fio::DirectoryObject) => Ok(()),
            other => Err(Kind::kind_of(&other)),
        }
    }

    pub(crate) fn kind_of2(representation: &fio::Representation) -> Kind {
        match representation {
            fio::Representation::Connector(_) => Kind::Service,
            fio::Representation::Directory(_) => Kind::Directory,
            fio::Representation::File(_) => Kind::File,
            fio::Representation::Symlink(_) => Kind::Symlink,
            _ => Kind::Unknown,
        }
    }

    fn expect_file2(representation: &fio::Representation) -> Result<(), Kind> {
        match representation {
            fio::Representation::File(fio::FileInfo { .. }) => Ok(()),
            other => Err(Kind::kind_of2(other)),
        }
    }

    fn expect_directory2(representation: &fio::Representation) -> Result<(), Kind> {
        match representation {
            fio::Representation::Directory(_) => Ok(()),
            other => Err(Kind::kind_of2(other)),
        }
    }
}

/// Opens the given `path` from the current namespace as a [`NodeProxy`].
///
/// The target is assumed to implement fuchsia.io.Node but this isn't verified. To connect to a
/// filesystem node which doesn't implement fuchsia.io.Node, use the functions in
/// [`fuchsia_component::client`] instead.
///
/// If the namespace path doesn't exist, or we fail to make the channel pair, this returns an
/// error. However, if incorrect flags are sent, or if the rest of the path sent to the filesystem
/// server doesn't exist, this will still return success. Instead, the returned NodeProxy channel
/// pair will be closed with an epitaph.
#[cfg(target_os = "fuchsia")]
pub fn open_in_namespace(path: &str, flags: fio::OpenFlags) -> Result<fio::NodeProxy, OpenError> {
    let (node, request) = fidl::endpoints::create_proxy().map_err(OpenError::CreateProxy)?;
    open_channel_in_namespace(path, flags, request)?;
    Ok(node)
}

/// Asynchronously opens the given [`path`] in the current namespace, serving the connection over
/// [`request`]. Once the channel is connected, any calls made prior are serviced.
///
/// The target is assumed to implement fuchsia.io.Node but this isn't verified. To connect to a
/// filesystem node which doesn't implement fuchsia.io.Node, use the functions in
/// [`fuchsia_component::client`] instead.
///
/// If the namespace path doesn't exist, this returns an error. However, if incorrect flags are
/// sent, or if the rest of the path sent to the filesystem server doesn't exist, this will still
/// return success. Instead, the [`request`] channel will be closed with an epitaph.
#[cfg(target_os = "fuchsia")]
pub fn open_channel_in_namespace(
    path: &str,
    flags: fio::OpenFlags,
    request: fidl::endpoints::ServerEnd<fio::NodeMarker>,
) -> Result<(), OpenError> {
    let namespace = fdio::Namespace::installed().map_err(OpenError::Namespace)?;
    namespace.open(path, flags, request.into_channel()).map_err(OpenError::Namespace)
}

/// Gracefully closes the node proxy from the remote end.
pub async fn close(node: fio::NodeProxy) -> Result<(), CloseError> {
    let result = node.close().await.map_err(CloseError::SendCloseRequest)?;
    result.map_err(|s| CloseError::CloseError(zx_status::Status::from_raw(s)))
}

/// Consume the first event from this NodeProxy's event stream, returning the proxy if it is
/// the expected type or an error otherwise.
pub(crate) async fn verify_node_describe_event(
    node: fio::NodeProxy,
) -> Result<fio::NodeProxy, OpenError> {
    match take_on_open_event(&node).await? {
        fio::NodeEvent::OnOpen_ { s: status, info } => {
            let () = zx_status::Status::ok(status).map_err(OpenError::OpenError)?;
            info.ok_or(OpenError::MissingOnOpenInfo)?;
        }
        fio::NodeEvent::OnRepresentation { .. } => (),
    }

    Ok(node)
}

/// Consume the first event from this DirectoryProxy's event stream, returning the proxy if it is
/// the expected type or an error otherwise.
pub(crate) async fn verify_directory_describe_event(
    node: fio::DirectoryProxy,
) -> Result<fio::DirectoryProxy, OpenError> {
    match take_on_open_event(&node).await? {
        fio::DirectoryEvent::OnOpen_ { s: status, info } => {
            let () = zx_status::Status::ok(status).map_err(OpenError::OpenError)?;
            let info = info.ok_or(OpenError::MissingOnOpenInfo)?;
            let () = Kind::expect_directory(*info).map_err(|actual| {
                OpenError::UnexpectedNodeKind { expected: Kind::Directory, actual }
            })?;
        }
        fio::DirectoryEvent::OnRepresentation { payload } => {
            let () = Kind::expect_directory2(&payload).map_err(|actual| {
                OpenError::UnexpectedNodeKind { expected: Kind::Directory, actual }
            })?;
        }
    }

    Ok(node)
}

/// Consume the first event from this FileProxy's event stream, returning the proxy if it is the
/// expected type or an error otherwise.
pub(crate) async fn verify_file_describe_event(
    node: fio::FileProxy,
) -> Result<fio::FileProxy, OpenError> {
    match take_on_open_event(&node).await? {
        fio::FileEvent::OnOpen_ { s: status, info } => {
            let () = zx_status::Status::ok(status).map_err(OpenError::OpenError)?;
            let info = info.ok_or(OpenError::MissingOnOpenInfo)?;
            let () = Kind::expect_file(*info)
                .map_err(|actual| OpenError::UnexpectedNodeKind { expected: Kind::File, actual })?;
        }
        fio::FileEvent::OnRepresentation { payload } => {
            let () = Kind::expect_file2(&payload)
                .map_err(|actual| OpenError::UnexpectedNodeKind { expected: Kind::File, actual })?;
        }
    }

    Ok(node)
}

pub(crate) trait OnOpenEventProducer {
    type Event;
    type Stream: futures::Stream<Item = Result<Self::Event, fidl::Error>> + Unpin;
    fn take_event_stream(&self) -> Self::Stream;
}

macro_rules! impl_on_open_event_producer {
    ($proxy:ty, $event:ty, $stream:ty) => {
        impl OnOpenEventProducer for $proxy {
            type Event = $event;
            type Stream = $stream;
            fn take_event_stream(&self) -> Self::Stream {
                self.take_event_stream()
            }
        }
    };
}

impl_on_open_event_producer!(fio::NodeProxy, fio::NodeEvent, fio::NodeEventStream);
impl_on_open_event_producer!(fio::FileProxy, fio::FileEvent, fio::FileEventStream);
impl_on_open_event_producer!(fio::DirectoryProxy, fio::DirectoryEvent, fio::DirectoryEventStream);

pub(crate) async fn take_on_open_event<T>(node: &T) -> Result<T::Event, OpenError>
where
    T: OnOpenEventProducer,
{
    node.take_event_stream()
        .next()
        .await
        .ok_or(OpenError::OnOpenEventStreamClosed)?
        .map_err(OpenError::OnOpenDecode)
}

#[cfg(test)]
mod tests {
    use {super::*, crate::OpenFlags, assert_matches::assert_matches, fuchsia_async as fasync};

    // open_in_namespace

    #[fasync::run_singlethreaded(test)]
    async fn open_in_namespace_opens_real_node() {
        let file_node = open_in_namespace("/pkg/data/file", OpenFlags::RIGHT_READABLE).unwrap();
        let protocol = file_node.query().await.unwrap();
        assert_eq!(protocol, fio::FILE_PROTOCOL_NAME.as_bytes());

        let dir_node = open_in_namespace("/pkg/data", OpenFlags::RIGHT_READABLE).unwrap();
        let protocol = dir_node.query().await.unwrap();
        assert_eq!(protocol, fio::DIRECTORY_PROTOCOL_NAME.as_bytes());
    }

    #[fasync::run_singlethreaded(test)]
    async fn open_in_namespace_opens_fake_node_under_of_root_namespace_entry() {
        let notfound = open_in_namespace("/pkg/fake", OpenFlags::RIGHT_READABLE).unwrap();
        // The open error is not detected until the proxy is interacted with.
        assert_matches!(close(notfound).await, Err(_));
    }

    #[fasync::run_singlethreaded(test)]
    async fn open_in_namespace_rejects_fake_root_namespace_entry() {
        assert_matches!(
            open_in_namespace("/fake", OpenFlags::RIGHT_READABLE),
            Err(OpenError::Namespace(zx_status::Status::NOT_FOUND))
        );
    }
}
