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

use {
    super::mocks::HostFn,
    fidl::endpoints::ServerEnd,
    fidl_fidl_examples_routing_echo::{EchoRequest, EchoRequestStream},
    fidl_fuchsia_io as fio,
    futures::TryStreamExt,
    std::{collections::HashMap, sync::Arc},
    vfs::{
        directory::{entry::DirectoryEntry, entry_container::Directory, immutable::simple as pfs},
        execution_scope::ExecutionScope,
        file::vmo::read_only,
        remote::remote_dir,
        service::host,
        tree_builder::TreeBuilder,
    },
};

/// Used to construct and then host an outgoing directory.
#[derive(Clone)]
pub struct OutDir {
    paths: HashMap<cm_types::Path, Arc<dyn DirectoryEntry>>,
}

impl OutDir {
    pub fn new() -> OutDir {
        OutDir { paths: HashMap::new() }
    }

    /// Add a `DirectoryEntry` served at the given path.
    pub fn add_entry(&mut self, path: cm_types::Path, entry: Arc<dyn DirectoryEntry>) {
        self.paths.insert(path, entry);
    }

    /// Adds a file providing the echo protocol at the given path.
    pub fn add_echo_protocol(&mut self, path: cm_types::Path) {
        self.add_entry(path, host(Self::echo_protocol_fn));
    }

    /// Adds a static file at the given path.
    pub fn add_static_file(&mut self, path: cm_types::Path, contents: &str) {
        self.add_entry(path, read_only(String::from(contents)));
    }

    /// Adds the given directory proxy at location "/data".
    pub fn add_directory_proxy(&mut self, test_dir_proxy: &fio::DirectoryProxy) {
        self.add_entry(
            "/data".parse().unwrap(),
            remote_dir(
                fuchsia_fs::directory::clone_no_describe(&test_dir_proxy, None)
                    .expect("could not clone directory"),
            ),
        );
    }

    /// Build the output directory.
    fn build_out_dir(&self) -> Result<Arc<pfs::Simple>, anyhow::Error> {
        let mut tree = TreeBuilder::empty_dir();
        // Add any external files.
        for (path, entry) in self.paths.iter() {
            let path = path.split();
            let path = path.iter().map(|x| x.as_str()).collect::<Vec<_>>();
            tree.add_entry(&path, entry.clone())?;
        }

        Ok(tree.build())
    }

    /// Returns a function that will host this outgoing directory on the given ServerEnd.
    pub fn host_fn(&self) -> HostFn {
        // Build the output directory.
        let dir = self.build_out_dir().expect("could not build out directory");

        // Construct a function. Each time it is invoked, we connect a new Zircon channel
        // `server_end` to the directory.
        Box::new(move |server_end: ServerEnd<fio::DirectoryMarker>| {
            dir.clone().open(
                ExecutionScope::new(),
                fio::OpenFlags::RIGHT_READABLE
                    | fio::OpenFlags::RIGHT_WRITABLE
                    | fio::OpenFlags::DIRECTORY,
                vfs::path::Path::dot(),
                ServerEnd::new(server_end.into_channel()),
            );
        })
    }

    /// Hosts a new protocol on `server_end` that implements `fidl.examples.routing.echo.Echo`.
    pub async fn echo_protocol_fn(mut stream: EchoRequestStream) {
        while let Some(EchoRequest::EchoString { value, responder }) =
            stream.try_next().await.unwrap()
        {
            responder.send(value.as_ref().map(|s| &**s)).unwrap();
        }
    }
}
