// 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::resolver::{Resolver, ResolverError, ResolverFut},
    anyhow::Error,
    cm_fidl_validator,
    fidl::endpoints::{ClientEnd, Proxy},
    fidl_fuchsia_io::{self as fio, DirectoryProxy},
    fidl_fuchsia_sys2 as fsys,
    fuchsia_url::boot_url::BootUrl,
    std::path::{Path, PathBuf},
};

pub static SCHEME: &str = "fuchsia-boot";

/// Resolves component URLs with the "fuchsia-boot" scheme, which supports loading components from
/// the /boot directory in component_manager's namespace.
///
/// On a typical system, this /boot directory is the bootfs served from the contents of the
/// 'ZBI_TYPE_STORAGE_BOOTFS' ZBI item by bootsvc, the process which starts component_manager.
///
/// URL syntax:
/// - fuchsia-boot:///path/within/bootfs#meta/component.cm
pub struct FuchsiaBootResolver {
    boot_proxy: DirectoryProxy,
}

impl FuchsiaBootResolver {
    /// Create a new FuchsiaBootResolver. This first checks whether a /boot directory is present in
    /// the namespace, and returns Ok(None) if not present. This is generally the case in unit and
    /// integration tests where this resolver is unused.
    pub fn new() -> Result<Option<FuchsiaBootResolver>, Error> {
        // Note that this check is synchronous. The async executor also likely is not being polled
        // yet, since this is called during startup.
        let bootfs_dir = Path::new("/boot");
        if !bootfs_dir.exists() {
            return Ok(None);
        }

        let proxy = io_util::open_directory_in_namespace(
            bootfs_dir.to_str().unwrap(),
            fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_EXECUTABLE,
        )?;
        Ok(Some(Self::new_from_directory(proxy)))
    }

    /// Create a new FuchsiaBootResolver that resolves URLs within the given directory. Used for
    /// injection in unit tests.
    fn new_from_directory(proxy: DirectoryProxy) -> FuchsiaBootResolver {
        FuchsiaBootResolver { boot_proxy: proxy }
    }

    async fn resolve_async<'a>(
        &'a self,
        component_url: &'a str,
    ) -> Result<fsys::Component, ResolverError> {
        // Parse URL.
        let url = BootUrl::parse(component_url)
            .map_err(|e| ResolverError::component_not_available(component_url, e))?;
        // Package path is 'canonicalized' to ensure that it is relative, since absolute paths will
        // be (inconsistently) rejected by fuchsia.io methods.
        let package_path = Path::new(io_util::canonicalize_path(url.path()));
        let res = url.resource().ok_or(ResolverError::url_missing_resource_error(component_url))?;
        let res_path = match package_path.to_str() {
            Some(".") => PathBuf::from(res),
            _ => package_path.join(res),
        };

        // Read component manifest from resource into a component decl.
        let cm_file = io_util::open_file(&self.boot_proxy, &res_path, fio::OPEN_RIGHT_READABLE)
            .map_err(|e| ResolverError::manifest_not_available(component_url, e))?;
        let component_decl = io_util::read_file_fidl(&cm_file)
            .await
            .map_err(|e| ResolverError::manifest_not_available(component_url, e))?;
        // Validate the component manifest
        cm_fidl_validator::validate(&component_decl)
            .map_err(|e| ResolverError::manifest_invalid(component_url, e))?;

        // Set up the fuchsia-boot path as the component's "package" namespace.
        let path_proxy = io_util::open_directory(
            &self.boot_proxy,
            package_path,
            fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_EXECUTABLE,
        )
        .map_err(|e| {
            ResolverError::component_not_available(
                component_url,
                e.context("failed to open package directory"),
            )
        })?;
        let package = fsys::Package {
            package_url: Some(url.root_url().to_string()),
            package_dir: Some(ClientEnd::new(path_proxy.into_channel().unwrap().into_zx_channel())),
            ..fsys::Package::EMPTY
        };

        Ok(fsys::Component {
            resolved_url: Some(component_url.to_string()),
            decl: Some(component_decl),
            package: Some(package),
            ..fsys::Component::EMPTY
        })
    }
}

impl Resolver for FuchsiaBootResolver {
    fn resolve<'a>(&'a self, component_url: &'a str) -> ResolverFut {
        Box::pin(self.resolve_async(component_url))
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        fidl::encoding::encode_persistent,
        fidl::endpoints::{create_proxy_and_stream, ServerEnd},
        fidl_fuchsia_data as fdata,
        fidl_fuchsia_io::{DirectoryMarker, DirectoryRequest, NodeMarker},
        fidl_fuchsia_sys2::ComponentDecl,
        fuchsia_async as fasync,
        futures::prelude::*,
        std::path::PathBuf,
        vfs::{
            self, directory::entry::DirectoryEntry, execution_scope::ExecutionScope,
            file::pcb::asynchronous::read_only_static, pseudo_directory,
        },
    };

    // Simulate a fake bootfs Directory service that only contains a single directory
    // ("packages/hello-world"), using our own package directory (hosted by the real pkgfs) as the
    // contents.
    // TODO(fxbug.dev/37534): This is implemented by manually handling the Directory.Open and forwarding
    // to the test's real package directory because Rust vfs does not yet support
    // OPEN_RIGHT_EXECUTABLE. Simplify in the future.
    // TODO: Switch this test to use a hardcoded manifest string & consider removing this test
    // manifest from the test package completely (after cleaning up other test dependencies).
    struct FakeBootfs;

    impl FakeBootfs {
        pub fn new() -> DirectoryProxy {
            let (proxy, mut stream) = create_proxy_and_stream::<DirectoryMarker>().unwrap();
            fasync::Task::local(async move {
                while let Some(request) = stream.try_next().await.unwrap() {
                    match request {
                        DirectoryRequest::Open {
                            flags,
                            mode: _,
                            path,
                            object,
                            control_handle: _,
                        } => Self::handle_open(&path, flags, object),
                        _ => panic!("Fake doesn't support request: {:?}", request),
                    }
                }
            })
            .detach();
            proxy
        }

        fn handle_open(path_str: &str, flags: u32, server_end: ServerEnd<NodeMarker>) {
            if path_str.is_empty() {
                // We don't support this in this fake, drop the server_end
                return;
            }
            let path = Path::new(path_str);
            let mut path_iter = path.iter();

            match path_iter.next().unwrap().to_str().unwrap() {
                "packages" => {
                    // The test URLs used below have "packages/" as the first path component
                    match path_iter.next().unwrap().to_str().unwrap() {
                        "hello-world" => {
                            // Connect the server_end by forwarding to our real package directory, which can handle
                            // OPEN_RIGHT_EXECUTABLE. Also, pass through the input flags here to ensure that we
                            // don't artificially pass the test (i.e. the resolver needs to ask for the appropriate
                            // rights).
                            let mut open_path = PathBuf::from("/pkg");
                            open_path.extend(path_iter);
                            io_util::connect_in_namespace(
                                open_path.to_str().unwrap(),
                                server_end.into_channel(),
                                flags,
                            )
                            .expect("failed to open path in namespace");
                        }
                        _ => return,
                    }
                }
                "meta" => {
                    // Provide a cm that will fail due to multiple runners being configured.
                    let out_dir = pseudo_directory! {
                        "meta" => pseudo_directory! {
                            "invalid.cm" => read_only_static(
                                encode_persistent(&mut fsys::ComponentDecl {
                                    program: None,
                                    uses: Some(vec![
                                        fsys::UseDecl::Runner(
                                            fsys::UseRunnerDecl {
                                                source_name: Some("elf".to_string()),
                                                ..fsys::UseRunnerDecl::EMPTY
                                            }
                                        ),
                                        fsys::UseDecl::Runner (
                                            fsys::UseRunnerDecl {
                                                source_name: Some("web".to_string()),
                                                ..fsys::UseRunnerDecl::EMPTY
                                            }
                                        )
                                    ]),
                                    exposes: None,
                                    offers: None,
                                    capabilities: None,
                                    children: None,
                                    collections: None,
                                    environments: None,
                                    facets: None,
                                    ..fsys::ComponentDecl::EMPTY
                                }).unwrap()
                            ),
                        }
                    };
                    out_dir.open(
                        ExecutionScope::new(),
                        flags,
                        fio::MODE_TYPE_FILE,
                        vfs::path::Path::validate_and_split(path_str)
                            .expect("received invalid path"),
                        server_end,
                    );
                }
                _ => return,
            }
        }
    }

    #[fasync::run_singlethreaded(test)]
    async fn hello_world_test() -> Result<(), Error> {
        let resolver = FuchsiaBootResolver::new_from_directory(FakeBootfs::new());

        let url = "fuchsia-boot:///packages/hello-world#meta/hello-world.cm";
        let component = resolver.resolve_async(url).await?;

        // Check that both the returned component manifest and the component manifest in
        // the returned package dir match the expected value. This also tests that
        // the resolver returned the right package dir.
        let fsys::Component { resolved_url, decl, package, .. } = component;
        assert_eq!(url, resolved_url.unwrap());
        let program = fdata::Dictionary {
            entries: Some(vec![fdata::DictionaryEntry {
                key: "binary".to_string(),
                value: Some(Box::new(fdata::DictionaryValue::Str("bin/hello_world".to_string()))),
            }]),
            ..fdata::Dictionary::EMPTY
        };
        let expected_decl = ComponentDecl {
            program: Some(program),
            uses: Some(vec![
                fsys::UseDecl::Runner(fsys::UseRunnerDecl {
                    source_name: Some("elf".to_string()),
                    ..fsys::UseRunnerDecl::EMPTY
                }),
                fsys::UseDecl::Protocol(fsys::UseProtocolDecl {
                    source: Some(fsys::Ref::Parent(fsys::ParentRef {})),
                    source_name: Some("fuchsia.logger.LogSink".to_string()),
                    target_path: Some("/svc/fuchsia.logger.LogSink".to_string()),
                    ..fsys::UseProtocolDecl::EMPTY
                }),
            ]),
            exposes: None,
            offers: None,
            facets: None,
            capabilities: None,
            children: None,
            collections: None,
            environments: None,
            ..ComponentDecl::EMPTY
        };
        assert_eq!(decl.unwrap(), expected_decl);

        let fsys::Package { package_url, package_dir, .. } = package.unwrap();
        assert_eq!(package_url.unwrap(), "fuchsia-boot:///packages/hello-world");

        let dir_proxy = package_dir.unwrap().into_proxy().unwrap();
        let path = Path::new("meta/hello-world.cm");
        let file_proxy = io_util::open_file(&dir_proxy, path, fio::OPEN_RIGHT_READABLE)
            .expect("could not open cm");
        assert_eq!(
            io_util::read_file_fidl::<ComponentDecl>(&file_proxy).await.expect("could not read cm"),
            expected_decl
        );

        // Try to load an executable file, like a binary, reusing the library_loader helper that
        // opens with OPEN_RIGHT_EXECUTABLE and gets a VMO with VMO_FLAG_EXEC.
        library_loader::load_vmo(&dir_proxy, "bin/hello_world")
            .await
            .expect("failed to open executable file");

        Ok(())
    }

    macro_rules! test_resolve_error {
        ($resolver:ident, $url:expr, $resolver_error_expected:ident) => {
            let url = $url;
            let res = $resolver.resolve_async(url).await;
            match res.err().expect("unexpected success") {
                ResolverError::$resolver_error_expected { url: u, .. } => {
                    assert_eq!(u, url);
                }
                e => panic!("unexpected error {:?}", e),
            }
        };
    }

    #[fuchsia_async::run_singlethreaded(test)]
    async fn resolve_errors_test() {
        let resolver = FuchsiaBootResolver::new_from_directory(FakeBootfs::new());
        test_resolve_error!(resolver, "fuchsia-boot:///#meta/invalid.cm", ManifestInvalid);
    }
}
