// 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 async_trait::async_trait;
use cm_types::NamespacePath;
use fidl::endpoints::ServerEnd;
use fidl::epitaph::ChannelEpitaphExt;
use fidl::prelude::*;
use fuchsia_runtime::{job_default, HandleInfo, HandleType};
use fuchsia_zircon::{self as zx, HandleBased, Status};
use futures::future::{BoxFuture, Either};
use futures::prelude::*;
use futures::stream::BoxStream;
use lazy_static::lazy_static;
use namespace::Namespace;
use thiserror::Error;
use tracing::*;
use {
    fidl_fuchsia_component as fcomp, fidl_fuchsia_component_runner as fcrunner,
    fidl_fuchsia_io as fio, fidl_fuchsia_process as fproc, fuchsia_async as fasync,
};

lazy_static! {
    pub static ref PKG_PATH: NamespacePath = "/pkg".parse().unwrap();
}

/// Object implementing this type can be killed by calling kill function.
#[async_trait]
pub trait Controllable {
    /// Should kill self and do cleanup.
    /// Should not return error or panic, should log error instead.
    async fn kill(&mut self);

    /// Stop the component. Once the component is stopped, the
    /// ComponentControllerControlHandle should be closed. If the component is
    /// not stopped quickly enough, kill will be called. The amount of time
    /// `stop` is allowed may vary based on a variety of factors.
    fn stop<'a>(&mut self) -> BoxFuture<'a, ()>;

    /// Perform any teardown tasks before closing the controller channel.
    fn teardown<'a>(&mut self) -> BoxFuture<'a, ()> {
        async {}.boxed()
    }

    /// Monitor any escrow requests from the component.
    fn on_escrow<'a>(&self) -> BoxStream<'a, fcrunner::ComponentControllerOnEscrowRequest> {
        futures::stream::empty().boxed()
    }
}

/// Holds information about the component that allows the controller to
/// interact with and control the component.
pub struct Controller<C: Controllable> {
    /// stream via which the component manager will ask the controller to
    /// manipulate the component
    request_stream: fcrunner::ComponentControllerRequestStream,

    /// Controllable object which controls the underlying component.
    /// This would be None once the object is killed.
    controllable: Option<C>,

    /// Task that forwards the `on_escrow` event.
    on_escrow_monitor: fasync::Task<()>,
}

pub struct ChannelEpitaph(u32);

impl ChannelEpitaph {
    pub fn ok() -> Self {
        static_assertions::const_assert_eq!(fuchsia_zircon_types::ZX_OK, 0);
        Self(0)
    }
}

impl From<ChannelEpitaph> for Status {
    fn from(value: ChannelEpitaph) -> Self {
        Status::from_raw(i32::try_from(value.0).unwrap_or_else(|_| i32::MAX))
    }
}

impl From<u32> for ChannelEpitaph {
    fn from(v: u32) -> Self {
        Self(v)
    }
}

impl TryFrom<Status> for ChannelEpitaph {
    type Error = std::num::TryFromIntError;
    fn try_from(value: Status) -> Result<Self, std::num::TryFromIntError> {
        Ok(Self(u32::try_from(value.into_raw())?))
    }
}

impl From<fcomp::Error> for ChannelEpitaph {
    fn from(value: fcomp::Error) -> Self {
        Self(u32::from(value.into_primitive()))
    }
}

impl<C: Controllable + 'static> Controller<C> {
    /// Creates new instance
    pub fn new(
        controllable: C,
        requests: fcrunner::ComponentControllerRequestStream,
    ) -> Controller<C> {
        let on_escrow = controllable.on_escrow();
        let on_escrow_monitor =
            fasync::Task::spawn(Self::monitor_events(on_escrow, requests.control_handle()));
        Controller { controllable: Some(controllable), request_stream: requests, on_escrow_monitor }
    }

    async fn serve_controller(&mut self) -> Result<(), ()> {
        while let Ok(Some(request)) = self.request_stream.try_next().await {
            match request {
                fcrunner::ComponentControllerRequest::Stop { control_handle: _c } => {
                    // Since stop takes some period of time to complete, call
                    // it in a separate context so we can respond to other
                    // requests.
                    let stop_func = self.stop();
                    fasync::Task::spawn(stop_func).detach();
                }
                fcrunner::ComponentControllerRequest::Kill { control_handle: _c } => {
                    self.kill().await;
                    return Ok(());
                }
            }
        }
        // The channel closed
        Err(())
    }

    async fn monitor_events(
        mut on_escrow: impl Stream<Item = fcrunner::ComponentControllerOnEscrowRequest> + Unpin + Send,
        control_handle: fcrunner::ComponentControllerControlHandle,
    ) {
        while let Some(event) = on_escrow.next().await {
            control_handle
                .send_on_escrow(event)
                .unwrap_or_else(|err| error!(%err, "failed to send OnEscrow event"));
        }
    }

    /// Serve the request stream held by this Controller. `exit_fut` should
    /// complete if the component exits and should return a value which is
    /// either 0 (ZX_OK) or one of the fuchsia.component/Error constants
    /// defined as valid in the fuchsia.component.runner/ComponentController
    /// documentation. This function will return after `exit_fut` completes
    /// or the request stream closes. In either case the request stream is
    /// closed once this function returns since the stream itself, which owns
    /// the channel, is dropped.
    pub async fn serve(mut self, exit_fut: impl Future<Output = ChannelEpitaph> + Unpin) {
        let result_code: ChannelEpitaph = {
            // Pin the server_controller future so we can use it with select
            let request_server = self.serve_controller();
            futures::pin_mut!(request_server);

            // Get the result of waiting for `exit_fut` to complete while also
            // polling the request server.
            match future::select(exit_fut, request_server).await {
                Either::Left((return_code, _controller_server)) => return_code,
                Either::Right((serve_result, pending_close)) => match serve_result {
                    Ok(()) => pending_close.await,
                    Err(_) => {
                        // Return directly because the controller channel
                        // closed so there's no point in an epitaph.
                        return;
                    }
                },
            }
        };

        // Before closing the controller channel, perform teardown tasks if the runner configured
        // them. This will only run if the component was not killed (otherwise `controllable` is
        // `None`).
        if let Some(mut controllable) = self.controllable.take() {
            controllable.teardown().await;
        }

        // Drain any escrow events.
        // TODO(https://fxbug.dev/326626515): Drain the escrow requests until no long readable
        // instead of waiting for an unbounded amount of time if `on_escrow` never completes.
        self.on_escrow_monitor.await;
        self.request_stream.control_handle().shutdown_with_epitaph(result_code.into());
    }

    /// Kill the job and shutdown control handle supplied to this function.
    async fn kill(&mut self) {
        if let Some(mut controllable) = self.controllable.take() {
            controllable.kill().await;
        }
    }

    /// If we have a Controllable, ask it to stop the component.
    fn stop<'a>(&mut self) -> BoxFuture<'a, ()> {
        if self.controllable.is_some() {
            self.controllable.as_mut().unwrap().stop()
        } else {
            async {}.boxed()
        }
    }
}

/// An error encountered trying to launch a component.
#[derive(Clone, Debug, PartialEq, Eq, Error)]
pub enum LaunchError {
    #[error("invalid binary path {}", _0)]
    InvalidBinaryPath(String),

    #[error("/pkg missing in the namespace")]
    MissingPkg,

    #[error("error loading executable: {:?}", _0)]
    LoadingExecutable(String),

    #[error("cannot convert proxy to channel")]
    DirectoryToChannel,

    #[error("cannot create channels: {}", _0)]
    ChannelCreation(fuchsia_zircon_status::Status),

    #[error("error loading 'lib' in /pkg: {:?}", _0)]
    LibLoadError(String),

    #[error("cannot create job: {}", _0)]
    JobCreation(fuchsia_zircon_status::Status),

    #[error("cannot duplicate job: {}", _0)]
    DuplicateJob(fuchsia_zircon_status::Status),

    #[error("cannot add args to launcher: {:?}", _0)]
    AddArgs(String),

    #[error("cannot add args to launcher: {:?}", _0)]
    AddHandles(String),

    #[error("cannot add args to launcher: {:?}", _0)]
    AddNames(String),

    #[error("cannot add env to launcher: {:?}", _0)]
    AddEnvirons(String),

    #[error("cannot set options for launcher: {:?}", _0)]
    SetOptions(String),
}

/// Arguments to `configure_launcher` function.
pub struct LauncherConfigArgs<'a> {
    /// relative binary path to /pkg in `ns`.
    pub bin_path: &'a str,

    /// Name of the binary to add to `LaunchInfo`. This will be truncated to
    /// `zx::sys::ZX_MAX_NAME_LEN` bytes.
    pub name: &'a str,

    /// The options used to create the process.
    pub options: zx::ProcessOptions,

    /// Arguments to binary. Binary path will be automatically
    /// prepended so that should not be passed as first argument.
    pub args: Option<Vec<String>>,

    /// Namespace for binary process to be launched.
    pub ns: Namespace,

    /// Job in which process is launched. If None, a child job would be created in default one.
    pub job: Option<zx::Job>,

    /// Extra handle infos to add. This function all ready adds handles for default job and svc
    /// loader.
    pub handle_infos: Option<Vec<fproc::HandleInfo>>,

    /// Extra names to add to namespace. by default only names from `ns` are added.
    pub name_infos: Option<Vec<fproc::NameInfo>>,

    /// Process environment to add to launcher.
    pub environs: Option<Vec<String>>,

    /// proxy for `fuchsia.proc.Launcher`.
    pub launcher: &'a fproc::LauncherProxy,

    /// Custom loader proxy. If None, /pkg/lib would be used to load libraries.
    pub loader_proxy_chan: Option<zx::Channel>,

    /// VMO containing mapping to executable binary. If None, it would be loaded from /pkg.
    pub executable_vmo: Option<zx::Vmo>,
}

/// Configures launcher to launch process using passed params and creates launch info.
/// This starts a library loader service, that will live as long as the handle for it given to the
/// launcher is alive.
pub async fn configure_launcher(
    config_args: LauncherConfigArgs<'_>,
) -> Result<fproc::LaunchInfo, LaunchError> {
    // Locate the '/pkg' directory proxy previously added to the new component's namespace.
    let pkg_dir = config_args.ns.get(&PKG_PATH).ok_or(LaunchError::MissingPkg)?;

    // library_loader provides a helper function that we use to load the main executable from the
    // package directory as a VMO in the same way that dynamic libraries are loaded. Doing this
    // first allows launching to fail quickly and clearly in case the main executable can't be
    // loaded with ZX_RIGHT_EXECUTE from the package directory.
    let executable_vmo = match config_args.executable_vmo {
        Some(v) => v,
        None => library_loader::load_vmo(pkg_dir, &config_args.bin_path)
            .await
            .map_err(|e| LaunchError::LoadingExecutable(e.to_string()))?,
    };

    let ll_client_chan = match config_args.loader_proxy_chan {
        None => {
            // The loader service should only be able to load files from `/pkg/lib`. Giving it a larger
            // scope is potentially a security vulnerability, as it could make it trivial for parts of
            // applications to get handles to things the application author didn't intend.
            let lib_proxy = fuchsia_component::directory::open_directory_no_describe(
                pkg_dir,
                "lib",
                fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_EXECUTABLE,
            )
            .map_err(|e| LaunchError::LibLoadError(e.to_string()))?;
            let (ll_client_chan, ll_service_chan) = zx::Channel::create();
            library_loader::start(lib_proxy.into(), ll_service_chan);
            ll_client_chan
        }
        Some(chan) => chan,
    };

    // Get the provided job to create the new process in, if one was provided, or else create a new
    // child job of this process's (this process that this code is running in) own 'default job'.
    let job = config_args
        .job
        .unwrap_or(job_default().create_child_job().map_err(LaunchError::JobCreation)?);

    // Build the command line args for the new process and send them to the launcher.
    let bin_arg = PKG_PATH
        .to_path_buf()
        .join(&config_args.bin_path)
        .to_str()
        .ok_or(LaunchError::InvalidBinaryPath(config_args.bin_path.to_string()))?
        .as_bytes()
        .to_vec();
    let mut all_args = vec![bin_arg];
    if let Some(args) = config_args.args {
        all_args.extend(args.into_iter().map(|s| s.into_bytes()));
    }
    config_args.launcher.add_args(&all_args).map_err(|e| LaunchError::AddArgs(e.to_string()))?;

    // Get any initial handles to provide to the new process, if any were provided by the caller.
    // Add handles for the new process's default job (by convention, this is the same job that the
    // new process is launched in) and the fuchsia.ldsvc.Loader service created above, then send to
    // the launcher.
    let job_dup =
        job.duplicate_handle(zx::Rights::SAME_RIGHTS).map_err(LaunchError::DuplicateJob)?;
    let mut handle_infos = config_args.handle_infos.unwrap_or(vec![]);
    handle_infos.append(&mut vec![
        fproc::HandleInfo {
            handle: ll_client_chan.into_handle(),
            id: HandleInfo::new(HandleType::LdsvcLoader, 0).as_raw(),
        },
        fproc::HandleInfo {
            handle: job_dup.into_handle(),
            id: HandleInfo::new(HandleType::DefaultJob, 0).as_raw(),
        },
    ]);
    config_args
        .launcher
        .add_handles(handle_infos)
        .map_err(|e| LaunchError::AddHandles(e.to_string()))?;

    if !config_args.options.is_empty() {
        config_args
            .launcher
            .set_options(config_args.options.bits())
            .map_err(|e| LaunchError::SetOptions(e.to_string()))?;
    }

    // Send environment variables for the new process, if any, to the launcher.
    let environs: Vec<_> = config_args.environs.unwrap_or(vec![]);
    if environs.len() > 0 {
        let environs_bytes: Vec<_> = environs.into_iter().map(|s| s.into_bytes()).collect();
        config_args
            .launcher
            .add_environs(&environs_bytes)
            .map_err(|e| LaunchError::AddEnvirons(e.to_string()))?;
    }

    // Combine any manually provided namespace entries with the provided Namespace, and
    // then send the new process's namespace to the launcher.
    let mut name_infos = config_args.name_infos.unwrap_or(vec![]);
    let ns: Vec<_> = config_args.ns.into();
    name_infos.extend(ns.into_iter());
    config_args.launcher.add_names(name_infos).map_err(|e| LaunchError::AddNames(e.to_string()))?;

    let name = truncate_str(config_args.name, zx::sys::ZX_MAX_NAME_LEN).to_owned();

    Ok(fproc::LaunchInfo { executable: executable_vmo, job, name })
}

/// Truncates `s` to be at most `max_len` bytes.
fn truncate_str(s: &str, max_len: usize) -> &str {
    if s.len() <= max_len {
        return s;
    }
    // TODO(https://github.com/rust-lang/rust/issues/93743): Use floor_char_boundary when stable.
    let mut index = max_len;
    while index > 0 && !s.is_char_boundary(index) {
        index -= 1;
    }
    &s[..index]
}

static CONNECT_ERROR_HELP: &'static str = "To learn more, see \
https://fuchsia.dev/go/components/connect-errors";

/// Sets an epitaph on `ComponentController` `server_end` for a runner failure and the outgoing
/// directory, and logs it.
pub fn report_start_error(
    err: zx::Status,
    err_str: String,
    resolved_url: &str,
    controller_server_end: ServerEnd<fcrunner::ComponentControllerMarker>,
) {
    let _ = controller_server_end.into_channel().close_with_epitaph(err);
    warn!("Failed to start component `{}`: {}\n{}", resolved_url, err_str, CONNECT_ERROR_HELP);
}

#[cfg(test)]
mod tests {
    use super::{
        configure_launcher, truncate_str, ChannelEpitaph, Controllable, Controller, LaunchError,
        LauncherConfigArgs,
    };
    use anyhow::{Context, Error};
    use assert_matches::assert_matches;
    use async_trait::async_trait;
    use fidl::endpoints::{create_endpoints, create_proxy, ClientEnd};
    use fidl_fuchsia_component_runner::{self as fcrunner, ComponentControllerProxy};
    use fuchsia_runtime::{HandleInfo, HandleType};
    use fuchsia_zircon::{self as zx, HandleBased};
    use futures::future::BoxFuture;
    use futures::poll;
    use futures::prelude::*;
    use namespace::{Namespace, NamespaceError};
    use std::pin::Pin;
    use std::task::Poll;
    use {fidl_fuchsia_io as fio, fidl_fuchsia_process as fproc, fuchsia_async as fasync};

    #[test]
    fn test_truncate_str() {
        assert_eq!(truncate_str("", 0), "");
        assert_eq!(truncate_str("", 1), "");

        assert_eq!(truncate_str("été", 0), "");
        assert_eq!(truncate_str("été", 1), "");
        assert_eq!(truncate_str("été", 2), "é");
        assert_eq!(truncate_str("été", 3), "ét");
        assert_eq!(truncate_str("été", 4), "ét");
        assert_eq!(truncate_str("été", 5), "été");
        assert_eq!(truncate_str("été", 6), "été");
    }

    struct FakeComponent<K, J>
    where
        K: FnOnce() + std::marker::Send,
        J: FnOnce() + std::marker::Send,
    {
        pub onkill: Option<K>,

        pub onstop: Option<J>,

        pub onteardown: Option<BoxFuture<'static, ()>>,
    }

    #[async_trait]
    impl<K: 'static, J: 'static> Controllable for FakeComponent<K, J>
    where
        K: FnOnce() + std::marker::Send,
        J: FnOnce() + std::marker::Send,
    {
        async fn kill(&mut self) {
            let func = self.onkill.take().unwrap();
            func();
        }

        fn stop<'a>(&mut self) -> BoxFuture<'a, ()> {
            let func = self.onstop.take().unwrap();
            async move { func() }.boxed()
        }

        fn teardown<'a>(&mut self) -> BoxFuture<'a, ()> {
            self.onteardown.take().unwrap()
        }
    }

    #[fuchsia::test]
    async fn test_kill_component() -> Result<(), Error> {
        let (sender, recv) = futures::channel::oneshot::channel::<()>();
        let (epitaph_tx, epitaph_rx) = futures::channel::oneshot::channel::<ChannelEpitaph>();
        const CHANNEL_EPITAPH: zx::Status = zx::Status::OK;
        let fake_component = FakeComponent {
            onkill: Some(move || {
                sender.send(()).unwrap();
                // After acknowledging that we received kill, send the epitaph
                // value so `serve` completes.
                let _ = epitaph_tx.send(CHANNEL_EPITAPH.try_into().unwrap());
            }),
            onstop: Some(|| {}),
            onteardown: Some(async {}.boxed()),
        };

        let (controller, client_proxy) = create_controller_and_proxy(fake_component)?;

        client_proxy.kill().expect("FIDL error returned from kill request to controller");

        let epitaph_receiver = Box::pin(async move { epitaph_rx.await.unwrap() });
        // this should return after kill call
        controller.serve(epitaph_receiver).await;

        // this means kill was called
        recv.await?;

        // Check the epitaph on the controller channel, this should match what
        // is sent by `epitaph_tx`
        assert_matches!(
            client_proxy.take_event_stream().try_next().await,
            Err(fidl::Error::ClientChannelClosed { status, .. }) if status == CHANNEL_EPITAPH
        );

        Ok(())
    }

    #[fuchsia::test]
    async fn test_stop_component() -> Result<(), Error> {
        let (sender, recv) = futures::channel::oneshot::channel::<()>();
        let (teardown_signal_tx, teardown_signal_rx) = futures::channel::oneshot::channel::<()>();
        let (teardown_fence_tx, teardown_fence_rx) = futures::channel::oneshot::channel::<()>();
        let (epitaph_tx, epitaph_rx) = futures::channel::oneshot::channel::<ChannelEpitaph>();
        const CHANNEL_EPITAPH: zx::Status = zx::Status::OK;

        let fake_component = FakeComponent {
            onstop: Some(move || {
                sender.send(()).unwrap();
                let _ = epitaph_tx.send(CHANNEL_EPITAPH.try_into().unwrap());
            }),
            onkill: Some(move || {}),
            onteardown: Some(
                async move {
                    teardown_signal_tx.send(()).unwrap();
                    teardown_fence_rx.await.unwrap();
                }
                .boxed(),
            ),
        };

        let (controller, client_proxy) = create_controller_and_proxy(fake_component)?;

        client_proxy.stop().expect("FIDL error returned from kill request to controller");

        let epitaph_receiver = Box::pin(async move { epitaph_rx.await.unwrap() });

        // This should return once the channel is closed, that is after stop and teardown
        let controller_serve = fasync::Task::spawn(controller.serve(epitaph_receiver));

        // This means stop was called
        recv.await?;

        // Teardown should be called
        teardown_signal_rx.await?;

        // Teardown is blocked. Verify there's no epitaph on the channel yet, then unblock it.
        let mut client_stream = client_proxy.take_event_stream();
        let mut client_stream_fut = client_stream.try_next();
        assert_matches!(poll!(Pin::new(&mut client_stream_fut)), Poll::Pending);
        teardown_fence_tx.send(()).unwrap();
        controller_serve.await;

        // Check the epitaph on the controller channel, this should match what
        // is sent by `epitaph_tx`
        assert_matches!(
            client_stream_fut.await,
            Err(fidl::Error::ClientChannelClosed { status, .. }) if status == CHANNEL_EPITAPH
        );

        Ok(())
    }

    #[fuchsia::test]
    fn test_stop_then_kill() -> Result<(), Error> {
        let mut exec = fasync::TestExecutor::new();
        let (sender, mut recv) = futures::channel::oneshot::channel::<()>();
        let (epitaph_tx, epitaph_rx) = futures::channel::oneshot::channel::<ChannelEpitaph>();
        const CHANNEL_EPITAPH: zx::Status = zx::Status::OK;

        // This component will only 'exit' after kill is called.
        let fake_component = FakeComponent {
            onstop: Some(move || {
                sender.send(()).unwrap();
            }),
            onkill: Some(move || {
                let _ = epitaph_tx.send(CHANNEL_EPITAPH.try_into().unwrap());
            }),
            onteardown: Some(async {}.boxed()),
        };

        let (controller, client_proxy) = create_controller_and_proxy(fake_component)?;
        // Send a stop request, note that the controller isn't even running
        // yet, but the request will be waiting in the channel when it does.
        client_proxy.stop().expect("FIDL error returned from stop request to controller");

        // Set up the controller to run.
        let epitaph_receiver = Box::pin(async move { epitaph_rx.await.unwrap() });
        let mut controller_fut = Box::pin(controller.serve(epitaph_receiver));

        // Run the serve loop until it is stalled, it shouldn't return because
        // stop doesn't automatically call exit.
        match exec.run_until_stalled(&mut controller_fut) {
            Poll::Pending => {}
            x => panic!("Serve future should have been pending but was not {:?}", x),
        }

        // Check that stop was called
        assert_eq!(exec.run_until_stalled(&mut recv), Poll::Ready(Ok(())));

        // Kill the component which should call the `onkill` we passed in.
        // This should cause the epitaph future to complete, which should then
        // cause the controller future to complete.
        client_proxy.kill().expect("FIDL error returned from kill request to controller");
        match exec.run_until_stalled(&mut controller_fut) {
            Poll::Ready(()) => {}
            x => panic!("Unexpected controller poll state {:?}", x),
        }

        // Check the controller channel closed with an epitaph that matches
        // what was sent in the `onkill` closure.
        let mut event_stream = client_proxy.take_event_stream();
        let mut next_fut = event_stream.try_next();
        assert_matches!(
            exec.run_until_stalled(&mut next_fut),
            Poll::Ready(Err(fidl::Error::ClientChannelClosed { status, .. })) if status == CHANNEL_EPITAPH
        );

        Ok(())
    }

    fn create_controller_and_proxy<K: 'static, J: 'static>(
        fake_component: FakeComponent<K, J>,
    ) -> Result<(Controller<FakeComponent<K, J>>, ComponentControllerProxy), Error>
    where
        K: FnOnce() + std::marker::Send,
        J: FnOnce() + std::marker::Send,
    {
        let (client_endpoint, server_endpoint) =
            create_endpoints::<fcrunner::ComponentControllerMarker>();

        // Get a proxy to the ComponentController channel.
        let controller_stream =
            server_endpoint.into_stream().context("failed to convert server end to controller")?;
        Ok((
            Controller::new(fake_component, controller_stream),
            client_endpoint.into_proxy().expect("conversion to proxy failed."),
        ))
    }

    mod launch_info {
        use fidl::endpoints::Proxy;

        use super::*;
        use anyhow::format_err;
        use futures::channel::oneshot;

        fn setup_empty_namespace() -> Result<Namespace, NamespaceError> {
            setup_namespace(false, vec![])
        }

        fn setup_namespace(
            include_pkg: bool,
            // All the handles created for this will have server end closed.
            // Clients cannot send messages on those handles in ns.
            extra_paths: Vec<&str>,
        ) -> Result<Namespace, NamespaceError> {
            let mut ns = Vec::<fcrunner::ComponentNamespaceEntry>::new();
            if include_pkg {
                let pkg_path = "/pkg".to_string();
                let pkg_chan = fuchsia_fs::directory::open_in_namespace(
                    "/pkg",
                    fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_EXECUTABLE,
                )
                .unwrap()
                .into_channel()
                .unwrap()
                .into_zx_channel();
                let pkg_handle = ClientEnd::new(pkg_chan);

                ns.push(fcrunner::ComponentNamespaceEntry {
                    path: Some(pkg_path),
                    directory: Some(pkg_handle),
                    ..Default::default()
                });
            }

            for path in extra_paths {
                let (client, _server) = create_endpoints::<fio::DirectoryMarker>();
                ns.push(fcrunner::ComponentNamespaceEntry {
                    path: Some(path.to_string()),
                    directory: Some(client),
                    ..Default::default()
                });
            }
            Namespace::try_from(ns)
        }

        #[derive(Default)]
        struct FakeLauncherServiceResults {
            names: Vec<String>,
            handles: Vec<u32>,
            args: Vec<String>,
            options: zx::ProcessOptions,
        }

        fn start_launcher(
        ) -> Result<(fproc::LauncherProxy, oneshot::Receiver<FakeLauncherServiceResults>), Error>
        {
            let (launcher_proxy, server_end) = create_proxy::<fproc::LauncherMarker>()?;
            let (sender, receiver) = oneshot::channel();
            fasync::Task::local(async move {
                let stream = server_end.into_stream().expect("error making stream");
                run_launcher_service(stream, sender)
                    .await
                    .expect("error running fake launcher service");
            })
            .detach();
            Ok((launcher_proxy, receiver))
        }

        async fn run_launcher_service(
            mut stream: fproc::LauncherRequestStream,
            sender: oneshot::Sender<FakeLauncherServiceResults>,
        ) -> Result<(), Error> {
            let mut res = FakeLauncherServiceResults::default();
            while let Some(event) = stream.try_next().await? {
                match event {
                    fproc::LauncherRequest::AddArgs { args, .. } => {
                        res.args.extend(
                            args.into_iter()
                                .map(|a| {
                                    std::str::from_utf8(&a)
                                        .expect("cannot convert bytes to utf8 string")
                                        .to_owned()
                                })
                                .collect::<Vec<String>>(),
                        );
                    }
                    fproc::LauncherRequest::AddEnvirons { .. } => {}
                    fproc::LauncherRequest::AddNames { names, .. } => {
                        res.names
                            .extend(names.into_iter().map(|m| m.path).collect::<Vec<String>>());
                    }
                    fproc::LauncherRequest::AddHandles { handles, .. } => {
                        res.handles.extend(handles.into_iter().map(|m| m.id).collect::<Vec<u32>>());
                    }
                    fproc::LauncherRequest::SetOptions { options, .. } => {
                        res.options = zx::ProcessOptions::from_bits_retain(options);
                    }
                    fproc::LauncherRequest::CreateWithoutStarting { .. } => {}
                    fproc::LauncherRequest::Launch { .. } => {}
                }
            }
            sender.send(res).map_err(|_e| format_err!("can't send result"))?;
            Ok(())
        }

        #[fuchsia::test]
        async fn missing_pkg() -> Result<(), Error> {
            let (launcher_proxy, _server_end) = create_proxy::<fproc::LauncherMarker>()?;
            let ns = setup_empty_namespace()?;

            assert_eq!(
                configure_launcher(LauncherConfigArgs {
                    bin_path: "bin/path",
                    name: "name",
                    args: None,
                    options: zx::ProcessOptions::empty(),
                    ns: ns,
                    job: None,
                    handle_infos: None,
                    name_infos: None,
                    environs: None,
                    launcher: &launcher_proxy,
                    loader_proxy_chan: None,
                    executable_vmo: None
                })
                .await,
                Err(LaunchError::MissingPkg),
            );

            drop(_server_end);
            Ok(())
        }

        #[fuchsia::test]
        async fn invalid_executable() -> Result<(), Error> {
            let (launcher_proxy, _server_end) = create_proxy::<fproc::LauncherMarker>()?;
            let ns = setup_namespace(true, vec![])?;

            match configure_launcher(LauncherConfigArgs {
                bin_path: "test/path",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: None,
            })
            .await
            .expect_err("should error out")
            {
                LaunchError::LoadingExecutable(_) => {}
                e => panic!("Expected LoadingExecutable error, got {:?}", e),
            }
            Ok(())
        }

        #[fuchsia::test]
        async fn invalid_pkg() -> Result<(), Error> {
            let (launcher_proxy, _server_end) = create_proxy::<fproc::LauncherMarker>()?;
            let ns = setup_namespace(false, vec!["/pkg"])?;

            match configure_launcher(LauncherConfigArgs {
                bin_path: "bin/path",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: None,
            })
            .await
            .expect_err("should error out")
            {
                LaunchError::LoadingExecutable(_) => {}
                e => panic!("Expected LoadingExecutable error, got {:?}", e),
            }
            Ok(())
        }

        #[fuchsia::test]
        async fn default_args() -> Result<(), Error> {
            let (launcher_proxy, recv) = start_launcher()?;

            let ns = setup_namespace(true, vec![])?;

            let _launch_info = configure_launcher(LauncherConfigArgs {
                bin_path: "bin/runner_lib_test",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: None,
            })
            .await?;

            drop(launcher_proxy);

            let ls = recv.await?;

            assert_eq!(ls.args, vec!("/pkg/bin/runner_lib_test".to_owned()));

            Ok(())
        }

        #[fasync::run_singlethreaded(test)]
        async fn custom_executable_vmo() -> Result<(), Error> {
            let (launcher_proxy, _recv) = start_launcher()?;

            let ns = setup_namespace(true, vec![])?;
            let vmo = zx::Vmo::create(100)?;
            vmo.write(b"my_data", 0)?;
            let launch_info = configure_launcher(LauncherConfigArgs {
                bin_path: "bin/runner_lib_test",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: Some(vmo),
            })
            .await?;

            let mut bytes: [u8; 10] = [0; 10];
            launch_info.executable.read(&mut bytes, 0)?;
            let expected = b"my_data";
            assert_eq!(bytes[0..expected.len()], expected[..]);
            Ok(())
        }

        #[fasync::run_singlethreaded(test)]
        async fn extra_args() -> Result<(), Error> {
            let (launcher_proxy, recv) = start_launcher()?;

            let ns = setup_namespace(true, vec![])?;

            let args = vec!["args1".to_owned(), "arg2".to_owned()];

            let _launch_info = configure_launcher(LauncherConfigArgs {
                bin_path: "bin/runner_lib_test",
                name: "name",
                args: Some(args.clone()),
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: None,
            })
            .await?;

            drop(launcher_proxy);

            let ls = recv.await?;

            let mut expected = vec!["/pkg/bin/runner_lib_test".to_owned()];
            expected.extend(args);
            assert_eq!(ls.args, expected);

            Ok(())
        }

        #[fasync::run_singlethreaded(test)]
        async fn namespace_added() -> Result<(), Error> {
            let (launcher_proxy, recv) = start_launcher()?;

            let ns = setup_namespace(true, vec!["/some_path1", "/some_path2"])?;

            let _launch_info = configure_launcher(LauncherConfigArgs {
                bin_path: "bin/runner_lib_test",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: None,
            })
            .await?;

            drop(launcher_proxy);

            let ls = recv.await?;

            let mut names = ls.names;
            names.sort();
            assert_eq!(
                names,
                vec!("/pkg", "/some_path1", "/some_path2")
                    .into_iter()
                    .map(|s| s.to_string())
                    .collect::<Vec<String>>()
            );

            Ok(())
        }

        #[fasync::run_singlethreaded(test)]
        async fn extra_namespace_entries() -> Result<(), Error> {
            let (launcher_proxy, recv) = start_launcher()?;

            let ns = setup_namespace(true, vec!["/some_path1", "/some_path2"])?;

            let mut names = vec![];

            let extra_paths = vec!["/extra1", "/extra2"];

            for path in &extra_paths {
                let (client, _server) = create_endpoints::<fio::DirectoryMarker>();

                names.push(fproc::NameInfo { path: path.to_string(), directory: client });
            }

            let _launch_info = configure_launcher(LauncherConfigArgs {
                bin_path: "bin/runner_lib_test",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: Some(names),
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: None,
            })
            .await?;

            drop(launcher_proxy);

            let ls = recv.await?;

            let mut paths = vec!["/pkg", "/some_path1", "/some_path2"];
            paths.extend(extra_paths.into_iter());
            paths.sort();

            let mut ls_names = ls.names;
            ls_names.sort();

            assert_eq!(ls_names, paths.into_iter().map(|s| s.to_string()).collect::<Vec<String>>());

            Ok(())
        }

        #[fasync::run_singlethreaded(test)]
        async fn handles_added() -> Result<(), Error> {
            let (launcher_proxy, recv) = start_launcher()?;

            let ns = setup_namespace(true, vec![])?;

            let _launch_info = configure_launcher(LauncherConfigArgs {
                bin_path: "bin/runner_lib_test",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: None,
            })
            .await?;

            drop(launcher_proxy);

            let ls = recv.await?;

            assert_eq!(
                ls.handles,
                vec!(
                    HandleInfo::new(HandleType::LdsvcLoader, 0).as_raw(),
                    HandleInfo::new(HandleType::DefaultJob, 0).as_raw()
                )
            );

            Ok(())
        }

        #[fasync::run_singlethreaded(test)]
        async fn handles_added_with_custom_loader_chan() -> Result<(), Error> {
            let (launcher_proxy, recv) = start_launcher()?;

            let (c1, _c2) = zx::Channel::create();

            let ns = setup_namespace(true, vec![])?;

            let _launch_info = configure_launcher(LauncherConfigArgs {
                bin_path: "bin/runner_lib_test",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: None,
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: Some(c1),
                executable_vmo: None,
            })
            .await?;

            drop(launcher_proxy);

            let ls = recv.await?;

            assert_eq!(
                ls.handles,
                vec!(
                    HandleInfo::new(HandleType::LdsvcLoader, 0).as_raw(),
                    HandleInfo::new(HandleType::DefaultJob, 0).as_raw()
                )
            );

            Ok(())
        }

        #[fasync::run_singlethreaded(test)]
        async fn extra_handles() -> Result<(), Error> {
            let (launcher_proxy, recv) = start_launcher()?;

            let ns = setup_namespace(true, vec![])?;

            let mut handle_infos = vec![];
            for fd in 0..3 {
                let (client, _server) = create_endpoints::<fio::DirectoryMarker>();
                handle_infos.push(fproc::HandleInfo {
                    handle: client.into_channel().into_handle(),
                    id: fd,
                });
            }

            let _launch_info = configure_launcher(LauncherConfigArgs {
                bin_path: "bin/runner_lib_test",
                name: "name",
                args: None,
                options: zx::ProcessOptions::empty(),
                ns: ns,
                job: None,
                handle_infos: Some(handle_infos),
                name_infos: None,
                environs: None,
                launcher: &launcher_proxy,
                loader_proxy_chan: None,
                executable_vmo: None,
            })
            .await?;

            drop(launcher_proxy);

            let ls = recv.await?;

            assert_eq!(
                ls.handles,
                vec!(
                    0,
                    1,
                    2,
                    HandleInfo::new(HandleType::LdsvcLoader, 0).as_raw(),
                    HandleInfo::new(HandleType::DefaultJob, 0).as_raw(),
                )
            );

            Ok(())
        }
    }
}
