// Copyright 2019 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 {
    crate::model::{addable_directory::AddableDirectory, error::ModelError, realm::WeakRealm},
    cm_rust::{CapabilityPath, ComponentDecl, ExposeDecl, UseDecl},
    directory_broker::{DirectoryBroker, RoutingFn},
    moniker::AbsoluteMoniker,
    std::collections::HashMap,
    vfs::directory::immutable::simple as pfs,
};

/// Represents the directory hierarchy of the exposed directory, not including the nodes for the
/// capabilities themselves.
pub(super) struct DirTree {
    directory_nodes: HashMap<String, Box<DirTree>>,
    broker_nodes: HashMap<String, RoutingFn>,
}

impl DirTree {
    /// Builds a directory hierarchy from a component's `uses` declarations.
    /// `routing_factory` is a closure that generates the routing function that will be called
    /// when a leaf node is opened.
    pub fn build_from_uses(
        routing_factory: impl Fn(WeakRealm, UseDecl) -> RoutingFn,
        realm: WeakRealm,
        decl: ComponentDecl,
    ) -> Self {
        let mut tree = DirTree { directory_nodes: HashMap::new(), broker_nodes: HashMap::new() };
        for use_ in decl.uses {
            tree.add_use_capability(&routing_factory, realm.clone(), &use_);
        }
        tree
    }

    /// Builds a directory hierarchy from a component's `exposes` declarations.
    /// `routing_factory` is a closure that generates the routing function that will be called
    /// when a leaf node is opened.
    pub fn build_from_exposes(
        routing_factory: impl Fn(WeakRealm, ExposeDecl) -> RoutingFn,
        realm: WeakRealm,
        decl: ComponentDecl,
    ) -> Self {
        let mut tree = DirTree { directory_nodes: HashMap::new(), broker_nodes: HashMap::new() };
        for expose in decl.exposes {
            tree.add_expose_capability(&routing_factory, realm.clone(), &expose);
        }
        tree
    }

    /// Installs the directory tree into `root_dir`.
    pub fn install<'entries>(
        self,
        abs_moniker: &AbsoluteMoniker,
        root_dir: &mut impl AddableDirectory,
    ) -> Result<(), ModelError> {
        for (name, subtree) in self.directory_nodes {
            let mut subdir = pfs::simple();
            subtree.install(abs_moniker, &mut subdir)?;
            root_dir.add_node(&name, subdir, abs_moniker)?;
        }
        for (name, route_fn) in self.broker_nodes {
            let node = DirectoryBroker::new(route_fn);
            root_dir.add_node(&name, node, abs_moniker)?;
        }
        Ok(())
    }

    fn add_use_capability(
        &mut self,
        routing_factory: &impl Fn(WeakRealm, UseDecl) -> RoutingFn,
        realm: WeakRealm,
        use_: &UseDecl,
    ) {
        // Event, EventStream and Runner capabilities are used by the framework
        // itself and not given to components directly.
        match use_ {
            cm_rust::UseDecl::Runner(_)
            | cm_rust::UseDecl::Event(_)
            | cm_rust::UseDecl::EventStream(_) => return,
            _ => {}
        }

        let path = match use_.path() {
            Some(path) => path,
            None => return,
        };
        let tree = self.to_directory_node(path);
        let routing_fn = routing_factory(realm, use_.clone());
        tree.broker_nodes.insert(path.basename.to_string(), routing_fn);
    }

    fn add_expose_capability(
        &mut self,
        routing_factory: &impl Fn(WeakRealm, ExposeDecl) -> RoutingFn,
        realm: WeakRealm,
        expose: &ExposeDecl,
    ) {
        let path = match expose {
            cm_rust::ExposeDecl::Service(d) => {
                format!("/{}", d.target_name).parse().expect("couldn't parse name as path")
            }
            cm_rust::ExposeDecl::Protocol(d) => {
                format!("/{}", d.target_name).parse().expect("couldn't parse name as path")
            }
            cm_rust::ExposeDecl::Directory(d) => {
                format!("/{}", d.target_name).parse().expect("couldn't parse name as path")
            }
            cm_rust::ExposeDecl::Runner(_) | cm_rust::ExposeDecl::Resolver(_) => {
                // Runners and resolvers do not add directory entries.
                return;
            }
        };
        let tree = self.to_directory_node(&path);
        let routing_fn = routing_factory(realm, expose.clone());
        tree.broker_nodes.insert(path.basename.to_string(), routing_fn);
    }

    fn to_directory_node(&mut self, path: &CapabilityPath) -> &mut DirTree {
        let components = path.dirname.split("/");
        let mut tree = self;
        for component in components {
            if !component.is_empty() {
                tree = tree.directory_nodes.entry(component.to_string()).or_insert(Box::new(
                    DirTree { directory_nodes: HashMap::new(), broker_nodes: HashMap::new() },
                ));
            }
        }
        tree
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        crate::model::{
            environment::Environment,
            realm::Realm,
            testing::{mocks, test_helpers, test_helpers::*},
        },
        cm_rust::{
            CapabilityName, CapabilityPath, ExposeDecl, ExposeDirectoryDecl, ExposeProtocolDecl,
            ExposeRunnerDecl, ExposeSource, ExposeTarget, UseDecl, UseDirectoryDecl,
            UseProtocolDecl, UseRunnerDecl, UseSource, UseStorageDecl,
        },
        fidl::endpoints::{ClientEnd, ServerEnd},
        fidl_fuchsia_io::MODE_TYPE_DIRECTORY,
        fidl_fuchsia_io::{DirectoryMarker, NodeMarker, OPEN_RIGHT_READABLE, OPEN_RIGHT_WRITABLE},
        fidl_fuchsia_io2 as fio2, fuchsia_zircon as zx,
        std::{
            convert::{TryFrom, TryInto},
            sync::{Arc, Weak},
        },
        vfs::{directory::entry::DirectoryEntry, execution_scope::ExecutionScope, path},
    };

    #[fuchsia_async::run_singlethreaded(test)]
    async fn build_from_uses() {
        // Call `build_from_uses` with a routing factory that routes to a mock directory or service,
        // and a `ComponentDecl` with `use` declarations.
        let routing_factory = mocks::proxy_use_routing_factory();
        let decl = ComponentDecl {
            uses: vec![
                UseDecl::Directory(UseDirectoryDecl {
                    source: UseSource::Parent,
                    source_name: "baz-dir".into(),
                    target_path: CapabilityPath::try_from("/in/data/hippo").unwrap(),
                    rights: fio2::Operations::Connect,
                    subdir: None,
                }),
                UseDecl::Protocol(UseProtocolDecl {
                    source: UseSource::Parent,
                    source_name: "baz-svc".into(),
                    target_path: CapabilityPath::try_from("/in/svc/hippo").unwrap(),
                }),
                UseDecl::Storage(UseStorageDecl {
                    source_name: "data".into(),
                    target_path: "/in/data/persistent".try_into().unwrap(),
                }),
                UseDecl::Storage(UseStorageDecl {
                    source_name: "cache".into(),
                    target_path: "/in/data/cache".try_into().unwrap(),
                }),
                UseDecl::Runner(UseRunnerDecl { source_name: CapabilityName::from("elf") }),
            ],
            ..default_component_decl()
        };
        let root_realm = Arc::new(Realm::new_root_realm(
            Environment::empty(),
            Weak::new(),
            Weak::new(),
            "test://root".to_string(),
        ));
        let tree = DirTree::build_from_uses(routing_factory, root_realm.as_weak(), decl.clone());

        // Convert the tree to a directory.
        let mut in_dir = pfs::simple();
        tree.install(&root_realm.abs_moniker, &mut in_dir)
            .expect("Unable to build pseudodirectory");
        let (in_dir_client, in_dir_server) = zx::Channel::create().unwrap();
        in_dir.open(
            ExecutionScope::new(),
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            MODE_TYPE_DIRECTORY,
            path::Path::empty(),
            ServerEnd::<NodeMarker>::new(in_dir_server.into()),
        );
        let in_dir_proxy = ClientEnd::<DirectoryMarker>::new(in_dir_client)
            .into_proxy()
            .expect("failed to create directory proxy");
        assert_eq!(
            vec!["in/data/cache", "in/data/hippo", "in/data/persistent", "in/svc/hippo"],
            test_helpers::list_directory_recursive(&in_dir_proxy).await
        );

        // Expect that calls on the directory nodes reach the mock directory/service.
        assert_eq!("friend", test_helpers::read_file(&in_dir_proxy, "in/data/hippo/hello").await);
        assert_eq!(
            "friend",
            test_helpers::read_file(&in_dir_proxy, "in/data/persistent/hello").await
        );
        assert_eq!("friend", test_helpers::read_file(&in_dir_proxy, "in/data/cache/hello").await);
        assert_eq!(
            "hippos".to_string(),
            test_helpers::call_echo(&in_dir_proxy, "in/svc/hippo").await
        );
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn build_from_exposes() {
        // Call `build_from_exposes` with a routing factory that routes to a mock directory or
        // service, and a `ComponentDecl` with `expose` declarations.
        let routing_factory = mocks::proxy_expose_routing_factory();
        let decl = ComponentDecl {
            exposes: vec![
                ExposeDecl::Directory(ExposeDirectoryDecl {
                    source: ExposeSource::Self_,
                    source_name: "baz-dir".into(),
                    target_name: "hippo-dir".into(),
                    target: ExposeTarget::Parent,
                    rights: Some(fio2::Operations::Connect),
                    subdir: None,
                }),
                ExposeDecl::Directory(ExposeDirectoryDecl {
                    source: ExposeSource::Self_,
                    source_name: "foo-dir".into(),
                    target_name: "bar-dir".into(),
                    target: ExposeTarget::Parent,
                    rights: Some(fio2::Operations::Connect),
                    subdir: None,
                }),
                ExposeDecl::Protocol(ExposeProtocolDecl {
                    source: ExposeSource::Self_,
                    source_name: "baz-svc".into(),
                    target_name: "hippo-svc".into(),
                    target: ExposeTarget::Parent,
                }),
                ExposeDecl::Runner(ExposeRunnerDecl {
                    source: ExposeSource::Self_,
                    source_name: CapabilityName::from("elf"),
                    target: ExposeTarget::Parent,
                    target_name: CapabilityName::from("elf"),
                }),
            ],
            ..default_component_decl()
        };
        let root_realm = Arc::new(Realm::new_root_realm(
            Environment::empty(),
            Weak::new(),
            Weak::new(),
            "test://root".to_string(),
        ));
        let tree = DirTree::build_from_exposes(routing_factory, root_realm.as_weak(), decl.clone());

        // Convert the tree to a directory.
        let mut expose_dir = pfs::simple();
        tree.install(&root_realm.abs_moniker, &mut expose_dir)
            .expect("Unable to build pseudodirectory");
        let (expose_dir_client, expose_dir_server) = zx::Channel::create().unwrap();
        expose_dir.open(
            ExecutionScope::new(),
            OPEN_RIGHT_READABLE | OPEN_RIGHT_WRITABLE,
            MODE_TYPE_DIRECTORY,
            path::Path::empty(),
            ServerEnd::<NodeMarker>::new(expose_dir_server.into()),
        );
        let expose_dir_proxy = ClientEnd::<DirectoryMarker>::new(expose_dir_client)
            .into_proxy()
            .expect("failed to create directory proxy");
        assert_eq!(
            vec!["bar-dir", "hippo-dir", "hippo-svc"],
            test_helpers::list_directory_recursive(&expose_dir_proxy).await
        );

        // Expect that calls on the directory nodes reach the mock directory/service.
        assert_eq!("friend", test_helpers::read_file(&expose_dir_proxy, "bar-dir/hello").await);
        assert_eq!("friend", test_helpers::read_file(&expose_dir_proxy, "hippo-dir/hello").await);
        assert_eq!(
            "hippos".to_string(),
            test_helpers::call_echo(&expose_dir_proxy, "hippo-svc").await
        );
    }
}
