// 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 {
    anyhow::{anyhow, Context},
    fidl::endpoints::{create_proxy, ClientEnd, Proxy},
    fidl_fuchsia_component_decl as fdecl, fidl_fuchsia_component_resolution as fresolution,
    fidl_fuchsia_io as fio,
    fidl_fuchsia_pkg::{PackageResolverMarker, PackageResolverProxy},
    fuchsia_component::{client::connect_to_protocol, server::ServiceFs},
    fuchsia_pkg::{
        transitional::{context_bytes_from_subpackages_map, subpackages_map_from_context_bytes},
        PackageDirectory,
    },
    fuchsia_url::{ComponentUrl, Hash, PackageUrl, RelativePackageUrl, RepositoryUrl},
    futures::prelude::*,
    log::*,
    std::collections::HashMap,
    thiserror::Error,
};

enum IncomingService {
    Resolver(fresolution::ResolverRequestStream),
}

#[fuchsia::main]
async fn main() -> anyhow::Result<()> {
    info!("started");
    let mut service_fs = ServiceFs::new_local();
    service_fs.dir("svc").add_fidl_service(IncomingService::Resolver);

    service_fs.take_and_serve_directory_handle().context("failed to serve outgoing namespace")?;

    service_fs
        .for_each_concurrent(None, |request| async {
            if let Err(err) = match request {
                IncomingService::Resolver(stream) => serve(stream).await,
            } {
                error!("failed to serve resolve request: {:#}", err);
            }
        })
        .await;

    Ok(())
}

async fn serve(mut stream: fresolution::ResolverRequestStream) -> anyhow::Result<()> {
    let package_resolver = connect_to_protocol::<PackageResolverMarker>()
        .context("failed to connect to PackageResolver service")?;
    while let Some(request) =
        stream.try_next().await.context("failed to read request from FIDL stream")?
    {
        match request {
            fresolution::ResolverRequest::Resolve { component_url, responder } => {
                let mut result =
                    resolve_component_without_context(&component_url, &package_resolver)
                        .await
                        .map_err(|err| {
                            let fidl_err = (&err).into();
                            warn!(
                                "failed to resolve component URL {}: {:#}",
                                component_url,
                                anyhow!(err)
                            );
                            fidl_err
                        });
                responder.send(&mut result).context("failed sending response")?;
            }
            fresolution::ResolverRequest::ResolveWithContext {
                component_url,
                context,
                responder,
            } => {
                let mut result =
                    resolve_component_with_context(&component_url, &context, &package_resolver)
                        .await
                        .map_err(|err| {
                            let fidl_err = (&err).into();
                            warn!(
                                "failed to resolve component URL {} with context {:?}: {:#}",
                                component_url,
                                context,
                                anyhow!(err)
                            );
                            fidl_err
                        });
                responder.send(&mut result).context("failed sending response")?;
            }
        }
    }
    Ok(())
}

async fn resolve_component_without_context(
    component_url: &str,
    package_resolver: &PackageResolverProxy,
) -> Result<fresolution::Component, ResolverError> {
    resolve_component(component_url, None, package_resolver).await
}

async fn resolve_component_with_context(
    component_url: &str,
    context: &Vec<u8>,
    package_resolver: &PackageResolverProxy,
) -> Result<fresolution::Component, ResolverError> {
    resolve_component(component_url, Some(context), package_resolver).await
}

async fn resolve_component(
    component_url_str: &str,
    some_incoming_context: Option<&Vec<u8>>,
    package_resolver: &PackageResolverProxy,
) -> Result<fresolution::Component, ResolverError> {
    let component_url = ComponentUrl::parse(component_url_str)?;
    let package =
        resolve_package_async(component_url.package_url(), some_incoming_context, package_resolver)
            .await?;

    // Read the component manifest (.cm file) from the package directory.
    let data = mem_util::open_file_data(&package.dir, component_url.resource())
        .await
        .map_err(ResolverError::ManifestNotFound)?;
    let raw_bytes = mem_util::bytes_from_data(&data).map_err(ResolverError::ReadingManifest)?;
    let decl: fdecl::Component = fidl::encoding::decode_persistent(&raw_bytes[..])
        .map_err(ResolverError::ParsingManifest)?;

    let config_values = if let Some(config_decl) = decl.config.as_ref() {
        // if we have a config declaration, we need to read the value file from the package dir
        let strategy =
            config_decl.value_source.as_ref().ok_or(ResolverError::MissingConfigSource)?;
        let config_path = match strategy {
            fdecl::ConfigValueSource::PackagePath(path) => path,
            other => return Err(ResolverError::UnsupportedConfigStrategy(other.to_owned())),
        };
        Some(
            mem_util::open_file_data(&package.dir, &config_path)
                .await
                .map_err(ResolverError::ConfigValuesNotFound)?,
        )
    } else {
        None
    };

    let package_dir = ClientEnd::new(
        package.dir.into_channel().expect("could not convert proxy to channel").into_zx_channel(),
    );
    Ok(fresolution::Component {
        url: Some(component_url_str.to_string()),
        resolution_context: Some(package.context),
        decl: Some(data),
        package: Some(fresolution::Package {
            url: Some(component_url.package_url().to_string()),
            directory: Some(package_dir),
            ..fresolution::Package::EMPTY
        }),
        config_values,
        ..fresolution::Component::EMPTY
    })
}

#[derive(Debug)]
struct ResolvedPackage {
    dir: fio::DirectoryProxy,
    context: Vec<u8>,
}

async fn resolve_package_async(
    package_url: &PackageUrl,
    some_incoming_context: Option<&Vec<u8>>,
    package_resolver: &PackageResolverProxy,
) -> Result<ResolvedPackage, ResolverError> {
    let (proxy, server_end) =
        create_proxy::<fio::DirectoryMarker>().expect("failed to create channel pair");
    let package_dir = PackageDirectory::from_proxy(proxy);

    let package_context = match package_url {
        PackageUrl::Relative(relative) => {
            let context = some_incoming_context
                .ok_or_else(|| ResolverError::RelativeUrlMissingContext(package_url.to_string()))?;
            // TODO(fxbug.dev/100060): Replace with `package_resolver.resolve_with_context` when
            // available.
            transitional::resolve_with_context(
                package_resolver,
                &package_dir,
                relative,
                context,
                server_end,
            )
            .await
        }
        PackageUrl::Absolute(absolute) => {
            // TODO(fxbug.dev/100060): Replace with `package_resolver.resolve` when available.
            transitional::resolve(package_resolver, &package_dir, absolute, server_end).await
        }
    }
    .map_err(ResolverError::IoError)?
    .map_err(|err| match err {
        fidl_fuchsia_pkg::ResolveError::PackageNotFound => ResolverError::PackageNotFound,
        fidl_fuchsia_pkg::ResolveError::RepoNotFound
        | fidl_fuchsia_pkg::ResolveError::UnavailableBlob
        | fidl_fuchsia_pkg::ResolveError::UnavailableRepoMetadata => ResolverError::Unavailable,
        fidl_fuchsia_pkg::ResolveError::NoSpace => ResolverError::NoSpace,
        _ => ResolverError::Internal,
    })?;
    Ok(ResolvedPackage { dir: package_dir.into_proxy(), context: package_context })
}

/// Implements the expected behavior of future Rust bindings for the upcoming
/// iteration of the FIDL API for `fuchsia.pkg.PackageResolver`, once updated to
/// support subpackages, by wrapping the existing API. Once the new version is
/// implemented, this module will be removed.
mod transitional {
    use {super::*, fidl::endpoints::ServerEnd, fuchsia_url::AbsolutePackageUrl};

    pub async fn resolve(
        package_resolver: &PackageResolverProxy,
        package_dir: &PackageDirectory,
        package_url: &AbsolutePackageUrl,
        dir_server_end: ServerEnd<fio::DirectoryMarker>,
    ) -> Result<Result<Vec<u8>, fidl_fuchsia_pkg::ResolveError>, fidl::Error> {
        let result = package_resolver.resolve(&package_url.to_string(), dir_server_end).await?;
        if let Err(err) = result {
            // The proxy call returned (outer result Ok), but it returned an Err (inner result)
            return Ok(Err(err));
        }
        let result = fabricate_package_context(package_url.repository(), package_dir)
            .await
            .map_err(|err: anyhow::Error| {
                error!("failed to fabricate package context: {:#}", err);
                fidl_fuchsia_pkg::ResolveError::Internal
            });
        Ok(result)
    }

    pub async fn resolve_with_context(
        package_resolver: &PackageResolverProxy,
        package_dir: &PackageDirectory,
        package_url: &RelativePackageUrl,
        context: &Vec<u8>,
        dir_server_end: ServerEnd<fio::DirectoryMarker>,
    ) -> Result<Result<Vec<u8>, fidl_fuchsia_pkg::ResolveError>, fidl::Error> {
        let (repo, hash) = match get_subpackage_repo_and_hash(package_url, context) {
            Ok(v) => v,
            Err(err) => {
                error!("failed to parse package context: {:?}", err);
                return Ok(Err(fidl_fuchsia_pkg::ResolveError::Internal));
            }
        };
        // TODO(fxbug.dev/100060):
        // This URL format (containing only the package hash with no absolute
        // package name) is a placeholder and not expected to actually be
        // accepted by the package resolver. We can add the package name, but,
        // but that would mean we would need to be able to get the package name
        // from the "subpackages" meta file, which is NOT part of the current
        // RFC spec. (The subpackage name does not need to match the absolute
        // package name. It's a parent package-specific internal name.). So
        // there are three choices:
        //   1. Leave it as-is and don't expect universe resolver to work until
        //      either option 2 or 3 is done. (This is what I'm doing for now,
        //      until we decide if we have to do 2 or can go directly to 3.)
        //   2. Add the absolute package name to the subpackages file format
        //      (for now), and to the package resolver URL below.
        //   3. Implement package resolver's "ResolveWithContext()" and move the
        //      logic for looking up subpackages to package resolver instead,
        //      where it actually belongs (according to the RFC).
        let pinned_subpackage_url = format!("{}/?hash={}", repo, hash);
        if let Err(err) = package_resolver.resolve(&pinned_subpackage_url, dir_server_end).await {
            return Err(err);
        }
        match fabricate_package_context(&repo, package_dir).await {
            Ok(package_context) => Ok(Ok(package_context)),
            Err(err) => {
                error!(
                    "failed to fabricate package context: {:#}, given package_url={}",
                    err, package_url
                );
                Ok(Err(fidl_fuchsia_pkg::ResolveError::Internal))
            }
        }
    }

    fn get_subpackage_repo_and_hash(
        subpackage: &RelativePackageUrl,
        context: &Vec<u8>,
    ) -> anyhow::Result<(RepositoryUrl, Hash)> {
        let info = PackageResolutionInfo::from_package_context(context)?;
        Ok((
            info.repo,
            info.subpackage_hashes
                .get(&subpackage)
                .ok_or_else(|| anyhow::format_err!("subpackage {} not found", subpackage))?
                .clone(),
        ))
    }

    async fn fabricate_package_context(
        repo: &RepositoryUrl,
        package_dir: &PackageDirectory,
    ) -> anyhow::Result<Vec<u8>> {
        let meta = package_dir.meta_subpackages().await?;
        PackageResolutionInfo::new(repo.clone(), meta.into_subpackages()).into_package_context()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PackageResolutionInfo {
    pub repo: RepositoryUrl,
    pub subpackage_hashes: HashMap<RelativePackageUrl, Hash>,
}

impl PackageResolutionInfo {
    pub fn new(repo: RepositoryUrl, subpackage_hashes: HashMap<RelativePackageUrl, Hash>) -> Self {
        Self { repo, subpackage_hashes }
    }

    pub fn from_package_context(context: &Vec<u8>) -> Result<Self, anyhow::Error> {
        let mut parts = context.split(|&b| b == b'\0');
        let repo = RepositoryUrl::parse_host(
            String::from_utf8(
                parts
                    .next()
                    .ok_or_else(|| anyhow::format_err!("Empty resolution context bytes"))?
                    .to_vec(),
            )
            .with_context(|| {
                format!(
                    "Error extracting package URL host from resolution context bytes: {:?}",
                    context
                )
            })?,
        )?;

        let subpackage_hashes = parts
            .next()
            .map(|bytes| {
                subpackages_map_from_context_bytes(&bytes.to_vec()).with_context(|| {
                    format!(
                        "Error extracting subpackages JSON from resolution context bytes: {:?}",
                        bytes
                    )
                })
            })
            .transpose()?
            .unwrap_or_default();
        Ok(Self { repo, subpackage_hashes })
    }

    pub fn into_package_context(self) -> anyhow::Result<Vec<u8>> {
        let Self { repo, subpackage_hashes } = self;
        let mut resolution_context = repo.host().as_bytes().to_vec();
        if let Some(mut context_bytes) = context_bytes_from_subpackages_map(&subpackage_hashes)? {
            resolution_context.push(b'\0');
            resolution_context.append(&mut context_bytes);
        }
        Ok(resolution_context)
    }
}

#[derive(Error, Debug)]
enum ResolverError {
    #[error("an unexpected error occurred")]
    Internal,

    #[error("invalid component URL")]
    InvalidUrl(#[from] fuchsia_url::errors::ParseError),

    #[error("manifest not found")]
    ManifestNotFound(#[source] mem_util::FileError),

    #[error("config values not found")]
    ConfigValuesNotFound(#[source] mem_util::FileError),

    #[error("package not found")]
    PackageNotFound,

    #[error("IO error")]
    IoError(#[source] fidl::Error),

    #[error("failed to deal with fuchsia.mem.Data")]
    ReadingManifest(#[source] mem_util::DataError),

    #[error("failed to parse compiled manifest to check for config")]
    ParsingManifest(#[source] fidl::Error),

    #[error("insufficient space to store package")]
    NoSpace,

    #[error("the component's package is temporarily unavailable")]
    Unavailable,

    #[error("component has config fields but does not have a config value lookup strategy")]
    MissingConfigSource,

    #[error("unsupported config value resolution strategy {_0:?}")]
    UnsupportedConfigStrategy(fdecl::ConfigValueSource),

    #[error("failed to create the resolution context")]
    CreatingContext(#[from] anyhow::Error),

    #[error("a context is required to resolve relative url: {0}")]
    RelativeUrlMissingContext(String),
}

impl From<&ResolverError> for fresolution::ResolverError {
    fn from(err: &ResolverError) -> fresolution::ResolverError {
        use {fresolution::ResolverError as ferr, ResolverError::*};
        match err {
            Internal => ferr::Internal,
            InvalidUrl(_) => ferr::InvalidArgs,
            ManifestNotFound { .. } => ferr::ManifestNotFound,
            ConfigValuesNotFound { .. } => ferr::ConfigValuesNotFound,
            PackageNotFound => ferr::PackageNotFound,
            ReadingManifest(_) | IoError(_) => ferr::Io,
            NoSpace => ferr::NoSpace,
            Unavailable => ferr::ResourceUnavailable,
            ParsingManifest(..) | MissingConfigSource | UnsupportedConfigStrategy(..) => {
                ferr::InvalidManifest
            }
            CreatingContext(_) => ferr::Internal,
            RelativeUrlMissingContext(_) => ferr::Internal,
        }
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        anyhow::Error,
        assert_matches::assert_matches,
        fidl::{encoding::encode_persistent_with_context, endpoints::ServerEnd},
        fidl_fuchsia_component_config as fconfig, fidl_fuchsia_component_decl as fdecl,
        fidl_fuchsia_component_resolution::ResolverMarker,
        fidl_fuchsia_io as fio, fidl_fuchsia_mem as fmem,
        fidl_fuchsia_pkg::{PackageResolverRequest, PackageResolverRequestStream},
        fuchsia_async as fasync,
        fuchsia_component::server as fserver,
        fuchsia_component_test::{
            Capability, ChildOptions, LocalComponentHandles, RealmBuilder, Ref, Route,
        },
        fuchsia_hash::Hash,
        fuchsia_pkg::MetaSubpackages,
        fuchsia_zircon::Vmo,
        futures::{channel::mpsc, join, lock::Mutex},
        std::{boxed::Box, iter::FromIterator, str::FromStr, sync::Arc},
        vfs::{
            directory::entry::DirectoryEntry,
            execution_scope::ExecutionScope,
            file::{vmo::asynchronous::read_only_static, vmo::asynchronous::NewVmo},
            path::Path,
            pseudo_directory,
        },
    };

    async fn resolve_package(
        package_url: &PackageUrl,
        package_resolver: &PackageResolverProxy,
    ) -> Result<ResolvedPackage, ResolverError> {
        resolve_package_async(package_url, None, package_resolver).await
    }

    async fn mock_pkg_resolver(
        trigger: Arc<Mutex<Option<mpsc::Sender<Result<(), Error>>>>>,
        handles: LocalComponentHandles,
    ) -> Result<(), Error> {
        let mut fs = fserver::ServiceFs::new();
        fs.dir("svc").add_fidl_service(
            move |mut req_stream: fidl_fuchsia_pkg::PackageResolverRequestStream| {
                let tx = trigger.clone();
                fasync::Task::local(async move {
                    while let Some(fidl_fuchsia_pkg::PackageResolverRequest::Resolve {
                        responder,
                        ..
                    }) =
                        req_stream.try_next().await.expect("Serving package resolver stream failed")
                    {
                        responder
                            .send(&mut Err(fidl_fuchsia_pkg::ResolveError::PackageNotFound))
                            .expect("failed sending package resolver response to client");

                        {
                            let mut lock = tx.lock().await;
                            let mut c = lock.take().unwrap();
                            c.send(Ok(())).await.expect("failed sending oneshot to test");
                            lock.replace(c);
                        }
                    }
                })
                .detach();
            },
        );

        fs.serve_connection(handles.outgoing_dir.into_channel())?;
        fs.collect::<()>().await;
        Ok(())
    }

    async fn package_requester(
        trigger: Arc<Mutex<Option<mpsc::Sender<Result<(), Error>>>>>,
        url: String,
        handles: LocalComponentHandles,
    ) -> Result<(), Error> {
        let resolver_proxy = handles.connect_to_protocol::<ResolverMarker>()?;
        let _ = resolver_proxy.resolve(&url).await?;
        fasync::Task::local(async move {
            let mut lock = trigger.lock().await;
            let mut c = lock.take().unwrap();
            c.send(Ok(())).await.expect("sending oneshot from package requester failed");
            lock.replace(c);
        })
        .detach();
        Ok(())
    }

    #[fasync::run_singlethreaded(test)]
    // Test that the default configuration which forwards requests to
    // PackageResolver works properly.
    async fn test_using_pkg_resolver() {
        let (sender, mut receiver) = mpsc::channel(2);
        let tx = Arc::new(Mutex::new(Some(sender)));
        let resolver_url =
            "fuchsia-pkg://fuchsia.com/universe-resolver-unittests#meta/universe-resolver-for-test.cm"
                .to_string();
        let requested_url =
            "fuchsia-pkg://fuchsia.com/test-pkg-request#meta/test-component.cm".to_string();
        let builder = RealmBuilder::new().await.expect("Failed to create test realm builder");
        let universe_resolver = builder
            .add_child("universe-resolver", resolver_url, ChildOptions::new())
            .await
            .expect("Failed add universe-resolver to test topology");
        let fake_pkg_resolver = builder
            .add_local_child(
                "fake-pkg-resolver",
                {
                    let sender = tx.clone();
                    move |handles: LocalComponentHandles| {
                        Box::pin(mock_pkg_resolver(sender.clone(), handles))
                    }
                },
                ChildOptions::new(),
            )
            .await
            .expect("Failed adding base resolver mock");
        let requesting_component = builder
            .add_local_child(
                "requesting-component",
                {
                    let sender = tx.clone();
                    move |handles: LocalComponentHandles| {
                        Box::pin(package_requester(sender.clone(), requested_url.clone(), handles))
                    }
                },
                ChildOptions::new().eager(),
            )
            .await
            .expect("Failed adding mock request component");
        builder
            .add_route(
                Route::new()
                    .capability(Capability::protocol_by_name("fuchsia.pkg.PackageResolver"))
                    .from(&fake_pkg_resolver)
                    .to(&universe_resolver),
            )
            .await
            .expect("Failed adding resolver route from fake-base-resolver to universe-resolver");
        builder
            .add_route(
                Route::new()
                    .capability(Capability::protocol_by_name(
                        "fuchsia.component.resolution.Resolver",
                    ))
                    .from(&universe_resolver)
                    .to(&requesting_component),
            )
            .await
            .expect("Failed adding resolver route from universe-resolver to requesting-component");
        builder
            .add_route(
                Route::new()
                    .capability(Capability::protocol_by_name("fuchsia.logger.LogSink"))
                    .from(Ref::parent())
                    .to(&universe_resolver)
                    .to(&fake_pkg_resolver)
                    .to(&requesting_component),
            )
            .await
            .expect("Failed adding LogSink route to test components");
        let _test_topo = builder.build().await.unwrap();

        receiver.next().await.expect("Unexpected error waiting for response").expect("error sent");
        receiver.next().await.expect("Unexpected error waiting for response").expect("error sent");
    }

    #[fuchsia::test]
    async fn resolve_package_succeeds() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let fs = pseudo_directory! {
                "test_file" => read_only_static(b"foo"),
            };
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { package_url, dir, responder } => {
                        assert_eq!(
                            package_url, "fuchsia-pkg://fuchsia.com/test",
                            "unexpected package URL"
                        );
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OpenFlags::RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::dot(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            let result =
                resolve_package(&"fuchsia-pkg://fuchsia.com/test".parse().unwrap(), &proxy).await;
            let package = result.expect("package resolver failed unexpectedly");
            let file = fuchsia_fs::directory::open_file(
                &package.dir,
                "test_file",
                fio::OpenFlags::RIGHT_READABLE,
            )
            .await
            .expect("failed to open 'test_file' from package resolver directory");
            let contents = fuchsia_fs::file::read(&file)
                .await
                .expect("failed to read 'test_file' contents from package resolver directory");
            assert_eq!(&contents, b"foo");
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_succeeds() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let cm_bytes = encode_persistent_with_context(
                &fidl::encoding::Context {
                    wire_format_version: fidl::encoding::WireFormatVersion::V2,
                },
                &mut fdecl::Component::EMPTY.clone(),
            )
            .expect("failed to encode ComponentDecl FIDL");
            let fs = pseudo_directory! {
                "meta" => pseudo_directory!{
                    "test.cm" => read_only_static(cm_bytes),
                },
            };
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { package_url, dir, responder } => {
                        assert_eq!(
                            package_url, "fuchsia-pkg://fuchsia.com/test",
                            "unexpected package URL"
                        );
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OpenFlags::RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::dot(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(
                resolve_component_without_context(
                    "fuchsia-pkg://fuchsia.com/test#meta/test.cm",
                    &proxy
                )
                .await,
                Ok(fresolution::Component {
                    decl: Some(fidl_fuchsia_mem::Data::Buffer(fidl_fuchsia_mem::Buffer { .. })),
                    ..
                })
            );
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_succeeds_with_hash() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let cm_bytes = encode_persistent_with_context(
                &fidl::encoding::Context {
                    wire_format_version: fidl::encoding::WireFormatVersion::V2,
                },
                &mut fdecl::Component::EMPTY.clone(),
            )
            .expect("failed to encode ComponentDecl FIDL");
            let fs = pseudo_directory! {
                "meta" => pseudo_directory!{
                    "test.cm" => read_only_static(cm_bytes),
                },
            };
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { package_url, dir, responder } => {
                        assert_eq!(package_url, "fuchsia-pkg://fuchsia.com/test?hash=9e3a3f63c018e2a4db0ef93903a87714f036e3e8ff982a7a2020eca86cc4677c", "unexpected package URL");
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OpenFlags::RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::dot(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(resolve_component_without_context("fuchsia-pkg://fuchsia.com/test?hash=9e3a3f63c018e2a4db0ef93903a87714f036e3e8ff982a7a2020eca86cc4677c#meta/test.cm", &proxy).await, Ok(_));
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_succeeds_with_vmo_manifest() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let fs = pseudo_directory! {
                "meta" => pseudo_directory!{
                    "test.cm" => vfs::file::vmo::read_only(|| async move {
                        let cm_bytes = encode_persistent_with_context(&fidl::encoding::Context{wire_format_version: fidl::encoding::WireFormatVersion::V2},&mut fdecl::Component::EMPTY.clone())
                            .expect("failed to encode ComponentDecl FIDL");
                        let capacity = cm_bytes.len() as u64;
                        let vmo = Vmo::create(capacity)?;
                        vmo.write(&cm_bytes, 0).expect("failed to write manifest bytes to vmo");
                        Ok(NewVmo { vmo, size: capacity, capacity })
                    }),
                },
            };
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { dir, responder, .. } => {
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OpenFlags::RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::dot(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(
                resolve_component_without_context(
                    "fuchsia-pkg://fuchsia.com/test#meta/test.cm",
                    &proxy
                )
                .await,
                Ok(fresolution::Component { decl: Some(fmem::Data::Buffer(_)), .. })
            );
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolves_component_in_subpackage_succeeds() {
        let parent_package_url = "fuchsia-pkg://fuchsia.com/toplevel-package";
        let parent_component_url = parent_package_url.to_owned() + "#meta/foo.cm";
        let subpackage_name = "my_subpackage";
        let subpackaged_component_fragment = "#meta/subfoo.cm";
        let subpackaged_component_relative_url =
            subpackage_name.to_owned() + subpackaged_component_fragment;
        let subpackage_hash = "facefacefacefacefacefacefacefacefacefacefacefacefacefacefaceface";
        let subpackage_hash_query_url =
            format!("fuchsia-pkg://fuchsia.com/?hash={}", subpackage_hash);
        let subpackages = MetaSubpackages::from_iter(vec![(
            RelativePackageUrl::parse(subpackage_name).unwrap(),
            Hash::from_str(subpackage_hash).unwrap(),
        )]);

        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let cm_bytes = encode_persistent_with_context(
                &fidl::encoding::Context {
                    wire_format_version: fidl::encoding::WireFormatVersion::V2,
                },
                &mut fdecl::Component::EMPTY.clone(),
            )
            .expect("failed to encode ComponentDecl FIDL");
            let parent_package_fs = pseudo_directory! {
                "meta" => pseudo_directory!{
                    "foo.cm" => read_only_static(cm_bytes.clone()),
                    "fuchsia.pkg" => pseudo_directory!{
                        "subpackages" => vfs::file::vmo::asynchronous::read_only_const(&serde_json::to_vec(&subpackages).unwrap()),
                    },
                },
            };
            let subpackage_fs = pseudo_directory! {
                "meta" => pseudo_directory!{
                    "subfoo.cm" => read_only_static(cm_bytes.clone()),
                },
            };
            let mut package_urls_to_resolve =
                vec![parent_package_url.to_owned(), subpackage_hash_query_url.to_owned()];
            let mut packages = vec![parent_package_fs, subpackage_fs];
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { package_url, dir, responder } => {
                        let expected = package_urls_to_resolve.remove(0);
                        assert_eq!(package_url, expected, "unexpected package URL");
                        let fs = packages.remove(0);
                        fs.open(
                            ExecutionScope::new(),
                            fio::OpenFlags::RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::dot(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            let parent_component = resolve_component_without_context(&parent_component_url, &proxy)
                .await
                .expect("failed to resolve parent_component");
            let resolution_context_repr =
                parent_component.resolution_context.clone().map(|context_bytes| {
                    let mut parts = context_bytes.split(|b| *b == b'\0');
                    let host = String::from_utf8(parts.next().unwrap_or(&[]).to_vec())
                        .unwrap_or_else(|e| format!("{:?}({:?})", e, context_bytes));
                    let subpackages = String::from_utf8(parts.next().unwrap_or(&[]).to_vec())
                        .unwrap_or_else(|e| format!("{:?}({:?})", e, context_bytes));
                    format!("host: {}, subpackages: {}", host, subpackages)
                });
            assert_matches!(parent_component.resolution_context, Some(..));
            assert_matches!(
                resolve_component_with_context(
                    &subpackaged_component_relative_url,
                    parent_component.resolution_context.as_ref().unwrap(),
                    &proxy
                )
                .await,
                Ok(fresolution::Component {
                    decl: Some(fidl_fuchsia_mem::Data::Buffer(fidl_fuchsia_mem::Buffer { .. })),
                    ..
                }),
                "Could not resolve subpackaged component '{}' from context '{:?}'",
                subpackaged_component_relative_url,
                resolution_context_repr
            );
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_fails_bad_connection() {
        let (proxy, server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        drop(server);
        assert_matches!(
            resolve_component_without_context(
                "fuchsia-pkg://fuchsia.com/test#meta/test.cm",
                &proxy
            )
            .await,
            Err(ResolverError::IoError(_))
        );
    }

    #[fuchsia::test]
    async fn resolve_component_fails_with_package_resolver_failure() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { responder, .. } => {
                        responder.send(&mut Err(fidl_fuchsia_pkg::ResolveError::NoSpace)).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(
                resolve_component_without_context(
                    "fuchsia-pkg://fuchsia.com/test#meta/test.cm",
                    &proxy
                )
                .await,
                Err(ResolverError::NoSpace)
            );
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_fails_with_component_not_found() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let fs = pseudo_directory! {};
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { dir, responder, .. } => {
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OpenFlags::RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::dot(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(
                resolve_component_without_context(
                    "fuchsia-pkg://fuchsia.com/test#meta/test.cm",
                    &proxy
                )
                .await,
                Err(ResolverError::ManifestNotFound(..))
            );
        };
        join!(server, client);
    }

    fn spawn_pkg_resolver(
        fs: Arc<impl vfs::directory::entry::DirectoryEntry>,
        mut server: PackageResolverRequestStream,
    ) -> fasync::Task<()> {
        fasync::Task::spawn(async move {
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { package_url, dir, responder } => {
                        assert_eq!(
                            package_url, "fuchsia-pkg://fuchsia.com/test",
                            "unexpected package URL"
                        );
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OpenFlags::RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::dot(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        })
    }

    #[fuchsia::test]
    async fn resolve_component_succeeds_with_config() {
        let (proxy, server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let cm_bytes = encode_persistent_with_context(
            &fidl::encoding::Context { wire_format_version: fidl::encoding::WireFormatVersion::V2 },
            &mut fdecl::Component {
                config: Some(fdecl::ConfigSchema {
                    value_source: Some(fdecl::ConfigValueSource::PackagePath(
                        "meta/test_with_config.cvf".to_string(),
                    )),
                    ..fdecl::ConfigSchema::EMPTY
                }),
                ..fdecl::Component::EMPTY
            },
        )
        .expect("failed to encode ComponentDecl FIDL");
        let cvf_bytes = encode_persistent_with_context(
            &fidl::encoding::Context { wire_format_version: fidl::encoding::WireFormatVersion::V2 },
            &mut fconfig::ValuesData { ..fconfig::ValuesData::EMPTY },
        )
        .expect("failed to encode ValuesData FIDL");
        let fs = pseudo_directory! {
            "meta" => pseudo_directory! {
                "test_with_config.cm" => read_only_static(cm_bytes),
                "test_with_config.cvf" => read_only_static(cvf_bytes),
            },
        };
        let _pkg_resolver = spawn_pkg_resolver(fs, server);
        assert_matches!(
            resolve_component_without_context(
                "fuchsia-pkg://fuchsia.com/test#meta/test_with_config.cm",
                &proxy
            )
            .await
            .unwrap(),
            fresolution::Component {
                decl: Some(fidl_fuchsia_mem::Data::Buffer(fidl_fuchsia_mem::Buffer { .. })),
                config_values: Some(fidl_fuchsia_mem::Data::Buffer(
                    fidl_fuchsia_mem::Buffer { .. }
                )),
                ..
            }
        );
    }

    #[fuchsia::test]
    async fn resolve_component_fails_missing_config_value_file() {
        let (proxy, server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let cm_bytes = encode_persistent_with_context(
            &fidl::encoding::Context { wire_format_version: fidl::encoding::WireFormatVersion::V2 },
            &mut fdecl::Component {
                config: Some(fdecl::ConfigSchema {
                    value_source: Some(fdecl::ConfigValueSource::PackagePath(
                        "meta/test_with_config.cvf".to_string(),
                    )),
                    ..fdecl::ConfigSchema::EMPTY
                }),
                ..fdecl::Component::EMPTY
            },
        )
        .expect("failed to encode ComponentDecl FIDL");
        let fs = pseudo_directory! {
            "meta" => pseudo_directory! {
                "test_with_config.cm" => read_only_static(cm_bytes),
            },
        };
        let _pkg_resolver = spawn_pkg_resolver(fs, server);
        assert_matches!(
            resolve_component_without_context(
                "fuchsia-pkg://fuchsia.com/test#meta/test_with_config.cm",
                &proxy
            )
            .await
            .unwrap_err(),
            ResolverError::ConfigValuesNotFound(_)
        );
    }

    #[fuchsia::test]
    async fn resolve_component_fails_bad_config_strategy() {
        let (proxy, server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let cm_bytes = encode_persistent_with_context(
            &fidl::encoding::Context { wire_format_version: fidl::encoding::WireFormatVersion::V2 },
            &mut fdecl::Component {
                config: Some(fdecl::ConfigSchema { ..fdecl::ConfigSchema::EMPTY }),
                ..fdecl::Component::EMPTY
            },
        )
        .expect("failed to encode ComponentDecl FIDL");
        let cvf_bytes = encode_persistent_with_context(
            &fidl::encoding::Context { wire_format_version: fidl::encoding::WireFormatVersion::V2 },
            &mut fconfig::ValuesData { ..fconfig::ValuesData::EMPTY },
        )
        .expect("failed to encode ValuesData FIDL");
        let fs = pseudo_directory! {
            "meta" => pseudo_directory! {
                "test_with_config.cm" => read_only_static(cm_bytes),
                "test_with_config.cvf" => read_only_static(cvf_bytes),
            },
        };
        let _pkg_resolver = spawn_pkg_resolver(fs, server);
        assert_matches!(
            resolve_component_without_context(
                "fuchsia-pkg://fuchsia.com/test#meta/test_with_config.cm",
                &proxy
            )
            .await
            .unwrap_err(),
            ResolverError::MissingConfigSource
        );
    }

    #[test]
    fn test_package_resolution_info() {
        let mut subpackages_map = HashMap::default();
        subpackages_map.insert(
            RelativePackageUrl::parse("subpackage_name").unwrap(),
            Hash::from_str("facefacefacefacefacefacefacefacefacefacefacefacefacefacefaceface")
                .unwrap(),
        );
        let info = PackageResolutionInfo::new(
            RepositoryUrl::parse_host("fuchsia.com".to_string()).unwrap(),
            subpackages_map,
        );
        let package_context = info.clone().into_package_context().unwrap();
        let info2 = PackageResolutionInfo::from_package_context(&package_context).unwrap();
        assert_eq!(info, info2);
    }
}
