// 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 anyhow::Error;
use fidl::endpoints::{create_proxy, ServerEnd};
use fidl_fuchsia_boot::{FactoryItemsMarker, FactoryItemsProxy};
use fidl_fuchsia_factory::{
    AlphaFactoryStoreProviderMarker, CastCredentialsFactoryStoreProviderMarker,
    MiscFactoryStoreProviderMarker, PlayReadyFactoryStoreProviderMarker,
    WeaveFactoryStoreProviderMarker, WidevineFactoryStoreProviderMarker,
};
use fuchsia_component::client::connect_to_protocol;
use fuchsia_fs::directory::DirentKind;
use futures::stream::TryStreamExt;
use nom::HexDisplay;
use structopt::StructOpt;
use {fidl_fuchsia_io as fio, fuchsia_async as fasync};

#[derive(Debug, StructOpt)]
#[structopt(
    name = "factoryctl command line tool, version 1.0.0",
    about = "Commands to view factory contents"
)]
pub enum Opt {
    #[structopt(name = "alpha")]
    Alpha(FactoryStoreCmd),
    #[structopt(name = "cast")]
    Cast(FactoryStoreCmd),
    #[structopt(name = "factory-items")]
    FactoryItems(FactoryItemsCmd),
    #[structopt(name = "misc")]
    Misc(FactoryStoreCmd),
    #[structopt(name = "playready")]
    PlayReady(FactoryStoreCmd),
    #[structopt(name = "weave")]
    Weave(FactoryStoreCmd),
    #[structopt(name = "widevine")]
    Widevine(FactoryStoreCmd),
}

#[derive(Debug, StructOpt)]
pub enum FactoryStoreCmd {
    #[structopt(name = "list")]
    List,

    #[structopt(name = "dump")]
    Dump { name: String },
}

#[derive(Debug, StructOpt)]
pub enum FactoryItemsCmd {
    #[structopt(name = "dump")]
    Dump { extra: u32 },
}

const HEX_DISPLAY_CHUNK_SIZE: usize = 16;

/// Walks the given `dir`, appending the full path to every file and returning the list.
async fn list_files(dir_proxy: &fio::DirectoryProxy) -> Result<Vec<String>, Error> {
    let mut stream = fuchsia_fs::directory::readdir_recursive(dir_proxy, /*timeout=*/ None);
    let mut out = vec![];
    while let Some(entry) = stream.try_next().await? {
        if entry.kind == DirentKind::File {
            out.push(entry.name);
        }
    }
    Ok(out)
}

/// Processes a command from the command line.
async fn process_cmd<F>(cmd: FactoryStoreCmd, mut connect_fn: F) -> Result<Vec<String>, Error>
where
    F: FnMut(ServerEnd<fio::DirectoryMarker>) -> (),
{
    let (dir_proxy, dir_server_end) = create_proxy::<fio::DirectoryMarker>()?;
    connect_fn(dir_server_end);

    let out = match cmd {
        FactoryStoreCmd::List => list_files(&dir_proxy).await?,
        FactoryStoreCmd::Dump { name } => {
            let file = fuchsia_fs::directory::open_file_no_describe(
                &dir_proxy,
                &name,
                fio::OpenFlags::RIGHT_READABLE,
            )?;
            let contents = fuchsia_fs::file::read(&file).await?;

            match std::str::from_utf8(&contents) {
                Ok(value) => {
                    vec![value.to_string()]
                }
                Err(_) => {
                    vec![contents.to_hex(HEX_DISPLAY_CHUNK_SIZE)]
                }
            }
        }
    };
    Ok(out)
}

async fn process_factory_items_cmd(
    cmd: FactoryItemsCmd,
    proxy: FactoryItemsProxy,
) -> Result<Vec<String>, Error> {
    let mut out = vec![];
    match cmd {
        FactoryItemsCmd::Dump { extra } => {
            let (vmo_opt, length) = proxy.get(extra).await.unwrap_or_else(|err| {
                panic!("Failed to get factory item with extra {}: {:?}", extra, err);
            });
            match vmo_opt {
                Some(ref vmo) if length > 0 => {
                    let mut buffer = vec![0; length as usize];
                    vmo.read(&mut buffer, 0)?;
                    out.push(buffer.to_hex(HEX_DISPLAY_CHUNK_SIZE));
                }
                _ => out.push("No valid vmo returned".to_string()),
            };
            out.push(format!("Length={}", length));
        }
    };
    Ok(out)
}

#[fasync::run_singlethreaded]
async fn main() -> Result<(), Error> {
    let opt = Opt::from_args();

    let out = match opt {
        Opt::Alpha(cmd) => {
            let proxy = connect_to_protocol::<AlphaFactoryStoreProviderMarker>()
                .expect("Failed to connect to AlphaFactoryStoreProvider service");
            process_cmd(cmd, move |server_end| proxy.get_factory_store(server_end).unwrap()).await
        }
        Opt::Cast(cmd) => {
            let proxy = connect_to_protocol::<CastCredentialsFactoryStoreProviderMarker>()
                .expect("Failed to connect to CastCredentialsFactoryStoreProvider service");
            process_cmd(cmd, move |server_end| proxy.get_factory_store(server_end).unwrap()).await
        }
        Opt::FactoryItems(cmd) => {
            let proxy = connect_to_protocol::<FactoryItemsMarker>()
                .expect("Failed to connect to FactoryItems service");
            process_factory_items_cmd(cmd, proxy).await
        }
        Opt::Misc(cmd) => {
            let proxy = connect_to_protocol::<MiscFactoryStoreProviderMarker>()
                .expect("Failed to connect to PlayReadyFactoryStoreProvider service");
            process_cmd(cmd, move |server_end| proxy.get_factory_store(server_end).unwrap()).await
        }
        Opt::PlayReady(cmd) => {
            let proxy = connect_to_protocol::<PlayReadyFactoryStoreProviderMarker>()
                .expect("Failed to connect to PlayReadyFactoryStoreProvider service");
            process_cmd(cmd, move |server_end| proxy.get_factory_store(server_end).unwrap()).await
        }
        Opt::Weave(cmd) => {
            let proxy = connect_to_protocol::<WeaveFactoryStoreProviderMarker>()
                .expect("Failed to connect to WeaveFactoryStoreProvider service");
            process_cmd(cmd, move |server_end| proxy.get_factory_store(server_end).unwrap()).await
        }
        Opt::Widevine(cmd) => {
            let proxy = connect_to_protocol::<WidevineFactoryStoreProviderMarker>()
                .expect("Failed to connect to WidevineFactoryStoreProvider service");
            process_cmd(cmd, move |server_end| proxy.get_factory_store(server_end).unwrap()).await
        }
    }?;

    // Write output to stdout.
    for l in out {
        println!("{}", l)
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use fidl_fuchsia_boot::{FactoryItemsRequest, FactoryItemsRequestStream};
    use fidl_fuchsia_factory::{
        AlphaFactoryStoreProviderRequest, AlphaFactoryStoreProviderRequestStream,
        CastCredentialsFactoryStoreProviderRequest,
        CastCredentialsFactoryStoreProviderRequestStream, MiscFactoryStoreProviderRequest,
        MiscFactoryStoreProviderRequestStream, PlayReadyFactoryStoreProviderRequest,
        PlayReadyFactoryStoreProviderRequestStream, WeaveFactoryStoreProviderRequest,
        WeaveFactoryStoreProviderRequestStream, WidevineFactoryStoreProviderRequest,
        WidevineFactoryStoreProviderRequestStream,
    };
    use fuchsia_component::server as fserver;
    use fuchsia_component_test::{
        Capability, ChildOptions, LocalComponentHandles, RealmBuilder, RealmInstance, Ref, Route,
    };
    use futures::StreamExt;
    use vfs::directory::entry_container::Directory;
    use vfs::execution_scope::ExecutionScope;
    use vfs::file::vmo::read_only;
    use vfs::tree_builder::TreeBuilder;
    use {fuchsia_async as fasync, fuchsia_zircon as zx};

    const ALPHA_TXT_FILE_NAME: &str = "txt/alpha.txt";
    const CAST_TXT_FILE_NAME: &str = "txt/cast.txt";
    const MISC_TXT_FILE_NAME: &str = "misc/misc.txt";
    const PLAYREADY_TXT_FILE_NAME: &str = "txt/playready.txt";
    const WEAVE_TXT_FILE_NAME: &str = "txt/weave.txt";
    const WIDEVINE_TXT_FILE_NAME: &str = "widevine.txt";

    const ALPHA_BIN_FILE_NAME: &str = "alpha.bin";
    const CAST_BIN_FILE_NAME: &str = "cast.bin";
    const MISC_BIN_FILE_NAME: &str = "bin/misc.bin";
    const PLAYREADY_BIN_FILE_NAME: &str = "playready/playready.bin";
    const WEAVE_BIN_FILE_NAME: &str = "weave.bin";
    const WIDEVINE_BIN_FILE_NAME: &str = "widevine.bin";

    const ALPHA_TXT_FILE_CONTENTS: &str = "an alpha file";
    const CAST_TXT_FILE_CONTENTS: &str = "a cast file";
    const MISC_TXT_FILE_CONTENTS: &str = "a misc file";
    const PLAYREADY_TXT_FILE_CONTENTS: &str = "a playready file";
    const WEAVE_TXT_FILE_CONTENTS: &str = "a weave file";
    const WIDEVINE_TXT_FILE_CONTENTS: &str = "a widevine file";

    const FACTORY_ITEM_CONTENTS: &[u8] = &[0xf0, 0xe8, 0x65, 0x94];
    const ALPHA_BIN_FILE_CONTENTS: &[u8] = &[0xaa, 0xbb, 0xcc, 0xdd];
    const CAST_BIN_FILE_CONTENTS: &[u8] = &[0x0, 0x18, 0xF1, 0x6d];
    const MISC_BIN_FILE_CONTENTS: &[u8] = &[0x0, 0xf3, 0x17, 0xb6];
    const PLAYREADY_BIN_FILE_CONTENTS: &[u8] = &[0x0e, 0xb8, 0x1a, 0xc6];
    const WEAVE_BIN_FILE_CONTENTS: &[u8] = &[0xab, 0xcd, 0xef, 0x1];
    const WIDEVINE_BIN_FILE_CONTENTS: &[u8] = &[0x0c, 0xee, 0x8a, 0x6f];

    enum ServiceMarkers {
        AlphaFactoryStore,
        CastCredentialsFactoryStore,
        MiscFactoryStore,
        PlayReadyFactoryStore,
        WeaveFactoryStore,
        WidevineFactoryStore,
    }

    fn start_test_dir(
        name: &'static str,
        contents: &'static str,
        name2: &'static str,
        contents2: &'static [u8],
    ) -> Result<fio::DirectoryProxy, Error> {
        let mut tree = TreeBuilder::empty_dir();
        tree.add_entry(&name.split("/").collect::<Vec<&str>>(), read_only(contents)).unwrap();
        tree.add_entry(&name2.split("/").collect::<Vec<&str>>(), read_only(contents2)).unwrap();
        let test_dir = tree.build();

        let (test_dir_proxy, test_dir_service) =
            fidl::endpoints::create_proxy::<fio::DirectoryMarker>()?;
        test_dir.open(
            ExecutionScope::new(),
            fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::DIRECTORY,
            vfs::path::Path::dot(),
            test_dir_service.into_channel().into(),
        );

        Ok(test_dir_proxy)
    }

    async fn items_mock(handles: LocalComponentHandles) -> Result<(), Error> {
        let mut fs = fserver::ServiceFs::new();
        let mut tasks = vec![];
        fs.dir("svc").add_fidl_service(move |mut stream: FactoryItemsRequestStream| {
            tasks.push(fasync::Task::local(async move {
                while let Some(FactoryItemsRequest::Get { extra: _, responder }) =
                    stream.try_next().await.expect("failed to serve factory_items service")
                {
                    let vmo = zx::Vmo::create(FACTORY_ITEM_CONTENTS.len() as u64).unwrap();
                    vmo.write(&FACTORY_ITEM_CONTENTS, 0).unwrap();
                    responder.send(Some(vmo), FACTORY_ITEM_CONTENTS.len() as u32).unwrap();
                }
            }));
        });
        fs.serve_connection(handles.outgoing_dir)?;
        fs.collect::<()>().await;
        Ok(())
    }

    async fn alpha_factory_store_handler(mut stream: AlphaFactoryStoreProviderRequestStream) {
        while let Some(AlphaFactoryStoreProviderRequest::GetFactoryStore {
            dir,
            control_handle: _,
        }) = stream.try_next().await.expect("failed to serve alpha_factory service")
        {
            let proxy = start_test_dir(
                ALPHA_TXT_FILE_NAME,
                ALPHA_TXT_FILE_CONTENTS,
                ALPHA_BIN_FILE_NAME,
                ALPHA_BIN_FILE_CONTENTS,
            )
            .unwrap();
            proxy.clone(fio::OpenFlags::RIGHT_READABLE, dir.into_channel().into()).unwrap();
        }
    }

    async fn cast_credentials_factory_store_handler(
        mut stream: CastCredentialsFactoryStoreProviderRequestStream,
    ) {
        while let Some(CastCredentialsFactoryStoreProviderRequest::GetFactoryStore {
            dir,
            control_handle: _,
        }) =
            stream.try_next().await.expect("failed to serve cast_credentials_factory service")
        {
            let proxy = start_test_dir(
                CAST_TXT_FILE_NAME,
                CAST_TXT_FILE_CONTENTS,
                CAST_BIN_FILE_NAME,
                CAST_BIN_FILE_CONTENTS,
            )
            .unwrap();
            proxy.clone(fio::OpenFlags::RIGHT_READABLE, dir.into_channel().into()).unwrap();
        }
    }

    async fn misc_factory_store_handler(mut stream: MiscFactoryStoreProviderRequestStream) {
        while let Some(MiscFactoryStoreProviderRequest::GetFactoryStore {
            dir,
            control_handle: _,
        }) = stream.try_next().await.expect("failed to serve misc_factory service")
        {
            let proxy = start_test_dir(
                MISC_TXT_FILE_NAME,
                MISC_TXT_FILE_CONTENTS,
                MISC_BIN_FILE_NAME,
                MISC_BIN_FILE_CONTENTS,
            )
            .unwrap();
            proxy.clone(fio::OpenFlags::RIGHT_READABLE, dir.into_channel().into()).unwrap();
        }
    }

    async fn play_ready_factory_store_handler(
        mut stream: PlayReadyFactoryStoreProviderRequestStream,
    ) {
        while let Some(PlayReadyFactoryStoreProviderRequest::GetFactoryStore {
            dir,
            control_handle: _,
        }) = stream.try_next().await.expect("failed to serve play_ready_factory service")
        {
            let proxy = start_test_dir(
                PLAYREADY_TXT_FILE_NAME,
                PLAYREADY_TXT_FILE_CONTENTS,
                PLAYREADY_BIN_FILE_NAME,
                PLAYREADY_BIN_FILE_CONTENTS,
            )
            .unwrap();
            proxy.clone(fio::OpenFlags::RIGHT_READABLE, dir.into_channel().into()).unwrap();
        }
    }

    async fn weave_factory_store_handler(mut stream: WeaveFactoryStoreProviderRequestStream) {
        while let Some(WeaveFactoryStoreProviderRequest::GetFactoryStore {
            dir,
            control_handle: _,
        }) = stream.try_next().await.expect("failed to serve weave_factory service")
        {
            let proxy = start_test_dir(
                WEAVE_TXT_FILE_NAME,
                WEAVE_TXT_FILE_CONTENTS,
                WEAVE_BIN_FILE_NAME,
                WEAVE_BIN_FILE_CONTENTS,
            )
            .unwrap();
            proxy.clone(fio::OpenFlags::RIGHT_READABLE, dir.into_channel().into()).unwrap();
        }
    }

    async fn widevine_factory_store_handler(mut stream: WidevineFactoryStoreProviderRequestStream) {
        while let Some(WidevineFactoryStoreProviderRequest::GetFactoryStore {
            dir,
            control_handle: _,
        }) = stream.try_next().await.expect("failed to serve widevine_factory service")
        {
            let proxy = start_test_dir(
                WIDEVINE_TXT_FILE_NAME,
                WIDEVINE_TXT_FILE_CONTENTS,
                WIDEVINE_BIN_FILE_NAME,
                WIDEVINE_BIN_FILE_CONTENTS,
            )
            .unwrap();
            proxy.clone(fio::OpenFlags::RIGHT_READABLE, dir.into_channel().into()).unwrap();
        }
    }

    // The server_mock! macro creates a ServiceFs to run a given mock under a given name.
    // Call like:
    //   server_mock!(foo_mock, FooProviderRequestStream, foo_handler);
    //
    //  It will create service called `foo_mock` that handles `FooProviderRequestStream` requests
    //  via the `foo_handler` function.
    macro_rules! server_mock {
        ( $func_name:ident, $strm:ty, $hndlr:ident ) => {
            async fn $func_name(handles: LocalComponentHandles) -> Result<(), Error> {
                let mut fs = fserver::ServiceFs::new();
                fs.dir("svc").add_fidl_service(move |stream: $strm| {
                    fasync::Task::spawn($hndlr(stream)).detach();
                });
                fs.serve_connection(handles.outgoing_dir)?;
                fs.collect::<()>().await;
                Ok(())
            }
        };
    }

    //----------------------------------------------------------------------------------------------
    // Create the mocks.
    //
    server_mock!(alpha_mock, AlphaFactoryStoreProviderRequestStream, alpha_factory_store_handler);

    server_mock!(
        cast_mock,
        CastCredentialsFactoryStoreProviderRequestStream,
        cast_credentials_factory_store_handler
    );

    server_mock!(misc_mock, MiscFactoryStoreProviderRequestStream, misc_factory_store_handler);

    server_mock!(
        play_ready_mock,
        PlayReadyFactoryStoreProviderRequestStream,
        play_ready_factory_store_handler
    );

    server_mock!(weave_mock, WeaveFactoryStoreProviderRequestStream, weave_factory_store_handler);

    server_mock!(
        widevine_mock,
        WidevineFactoryStoreProviderRequestStream,
        widevine_factory_store_handler
    );

    //
    // End creating the mocks.
    //----------------------------------------------------------------------------------------------

    async fn get_factory_items_output(
        realm: &RealmInstance,
        cmd: FactoryItemsCmd,
    ) -> Result<Vec<String>, Error> {
        let factory_items_proxy =
            realm.root.connect_to_protocol_at_exposed_dir::<FactoryItemsMarker>()?;
        process_factory_items_cmd(cmd, factory_items_proxy).await
    }

    async fn get_factory_store_output(
        realm: &RealmInstance,
        marker: ServiceMarkers,
        cmd: FactoryStoreCmd,
    ) -> Result<Vec<String>, Error> {
        match marker {
            ServiceMarkers::AlphaFactoryStore => {
                let proxy = realm
                    .root
                    .connect_to_protocol_at_exposed_dir::<AlphaFactoryStoreProviderMarker>()?;
                process_cmd(cmd, |server_end| proxy.get_factory_store(server_end).unwrap()).await
            }
            ServiceMarkers::CastCredentialsFactoryStore => {
                let proxy = realm
                        .root
                        .connect_to_protocol_at_exposed_dir::<CastCredentialsFactoryStoreProviderMarker>()?;
                process_cmd(cmd, |server_end| proxy.get_factory_store(server_end).unwrap()).await
            }
            ServiceMarkers::MiscFactoryStore => {
                let proxy = realm
                    .root
                    .connect_to_protocol_at_exposed_dir::<MiscFactoryStoreProviderMarker>()?;
                process_cmd(cmd, |server_end| proxy.get_factory_store(server_end).unwrap()).await
            }
            ServiceMarkers::PlayReadyFactoryStore => {
                let proxy = realm
                    .root
                    .connect_to_protocol_at_exposed_dir::<PlayReadyFactoryStoreProviderMarker>()?;
                process_cmd(cmd, |server_end| proxy.get_factory_store(server_end).unwrap()).await
            }
            ServiceMarkers::WeaveFactoryStore => {
                let proxy = realm
                    .root
                    .connect_to_protocol_at_exposed_dir::<WeaveFactoryStoreProviderMarker>()?;
                process_cmd(cmd, |server_end| proxy.get_factory_store(server_end).unwrap()).await
            }
            ServiceMarkers::WidevineFactoryStore => {
                let proxy = realm
                    .root
                    .connect_to_protocol_at_exposed_dir::<WidevineFactoryStoreProviderMarker>()?;
                process_cmd(cmd, |server_end| proxy.get_factory_store(server_end).unwrap()).await
            }
        }
    }

    // The add_mock! macro adds a given mock component as a local child to the given BuildRealm
    // with the given name.
    macro_rules! add_mock {
        ( $builder:ident, $name:literal, $mock:ident ) => {
            $builder
                .add_local_child(
                    $name,
                    move |handles: LocalComponentHandles| Box::pin($mock(handles)),
                    ChildOptions::new(),
                )
                .await?
        };
    }

    // The add_route! macro routes the named capability from the given component to the parent.
    macro_rules! add_route {
        ( $builder:ident, $name:literal, $comp:ident ) => {
            $builder
                .add_route(
                    Route::new()
                        .capability(Capability::protocol_by_name($name))
                        .from(&$comp)
                        .to(Ref::parent()),
                )
                .await?
        };
    }

    async fn build_realm() -> Result<RealmInstance, fuchsia_component_test::error::Error> {
        let builder = RealmBuilder::new().await?;

        // Add the mock components.
        let factory_items = add_mock!(builder, "factory_items", items_mock);
        let alpha_store = add_mock!(builder, "alpha", alpha_mock);
        let cast_store = add_mock!(builder, "cast", cast_mock);
        let misc_store = add_mock!(builder, "misc", misc_mock);
        let play_ready_store = add_mock!(builder, "play_ready", play_ready_mock);
        let weave_store = add_mock!(builder, "weave", weave_mock);
        let widevine_store = add_mock!(builder, "widevine", widevine_mock);

        // Add the capabilities.
        builder
            .add_route(
                Route::new()
                    .capability(Capability::protocol_by_name("fuchsia.logger.LogSink"))
                    .from(Ref::parent())
                    .to(&factory_items)
                    .to(&alpha_store)
                    .to(&cast_store)
                    .to(&misc_store)
                    .to(&play_ready_store)
                    .to(&weave_store)
                    .to(&widevine_store),
            )
            .await?;

        // Route these capabilities to the parent.
        add_route!(builder, "fuchsia.boot.FactoryItems", factory_items);
        add_route!(builder, "fuchsia.factory.AlphaFactoryStoreProvider", alpha_store);
        add_route!(builder, "fuchsia.factory.CastCredentialsFactoryStoreProvider", cast_store);
        add_route!(builder, "fuchsia.factory.MiscFactoryStoreProvider", misc_store);
        add_route!(builder, "fuchsia.factory.PlayReadyFactoryStoreProvider", play_ready_store);
        add_route!(builder, "fuchsia.factory.WeaveFactoryStoreProvider", weave_store);
        add_route!(builder, "fuchsia.factory.WidevineFactoryStoreProvider", widevine_store);

        builder.build().await
    }

    #[fasync::run_singlethreaded(test)]
    async fn list_files() -> Result<(), Error> {
        let realm = build_realm().await?;
        for (marker, bin_name, txt_name) in vec![
            (ServiceMarkers::AlphaFactoryStore, ALPHA_BIN_FILE_NAME, ALPHA_TXT_FILE_NAME),
            (ServiceMarkers::CastCredentialsFactoryStore, CAST_BIN_FILE_NAME, CAST_TXT_FILE_NAME),
            (ServiceMarkers::MiscFactoryStore, MISC_BIN_FILE_NAME, MISC_TXT_FILE_NAME),
            (
                ServiceMarkers::PlayReadyFactoryStore,
                PLAYREADY_BIN_FILE_NAME,
                PLAYREADY_TXT_FILE_NAME,
            ),
            (ServiceMarkers::WeaveFactoryStore, WEAVE_BIN_FILE_NAME, WEAVE_TXT_FILE_NAME),
            (ServiceMarkers::WidevineFactoryStore, WIDEVINE_BIN_FILE_NAME, WIDEVINE_TXT_FILE_NAME),
        ] {
            let out = get_factory_store_output(&realm, marker, FactoryStoreCmd::List {}).await?;
            assert_eq!(out.len(), 2);
            assert_eq!(out[0], bin_name.to_string());
            assert_eq!(out[1], txt_name.to_string());
        }

        Ok(())
    }

    #[fasync::run_singlethreaded(test)]
    async fn dump_text_files() -> Result<(), Error> {
        let realm = build_realm().await?;
        for (marker, name, contents) in vec![
            (ServiceMarkers::AlphaFactoryStore, ALPHA_TXT_FILE_NAME, ALPHA_TXT_FILE_CONTENTS),
            (
                ServiceMarkers::CastCredentialsFactoryStore,
                CAST_TXT_FILE_NAME,
                CAST_TXT_FILE_CONTENTS,
            ),
            (ServiceMarkers::MiscFactoryStore, MISC_TXT_FILE_NAME, MISC_TXT_FILE_CONTENTS),
            (
                ServiceMarkers::PlayReadyFactoryStore,
                PLAYREADY_TXT_FILE_NAME,
                PLAYREADY_TXT_FILE_CONTENTS,
            ),
            (ServiceMarkers::WeaveFactoryStore, WEAVE_TXT_FILE_NAME, WEAVE_TXT_FILE_CONTENTS),
            (
                ServiceMarkers::WidevineFactoryStore,
                WIDEVINE_TXT_FILE_NAME,
                WIDEVINE_TXT_FILE_CONTENTS,
            ),
        ] {
            let out = get_factory_store_output(
                &realm,
                marker,
                FactoryStoreCmd::Dump { name: name.to_string() },
            )
            .await?;
            assert_eq!(out.len(), 1);
            assert!(out[0].contains(contents));
        }
        Ok(())
    }

    #[fasync::run_singlethreaded(test)]
    async fn dump_binary_files() -> Result<(), Error> {
        let realm = build_realm().await?;
        for (marker, name, contents) in vec![
            (ServiceMarkers::AlphaFactoryStore, ALPHA_BIN_FILE_NAME, ALPHA_BIN_FILE_CONTENTS),
            (
                ServiceMarkers::CastCredentialsFactoryStore,
                CAST_BIN_FILE_NAME,
                CAST_BIN_FILE_CONTENTS,
            ),
            (ServiceMarkers::MiscFactoryStore, MISC_BIN_FILE_NAME, MISC_BIN_FILE_CONTENTS),
            (
                ServiceMarkers::PlayReadyFactoryStore,
                PLAYREADY_BIN_FILE_NAME,
                PLAYREADY_BIN_FILE_CONTENTS,
            ),
            (ServiceMarkers::WeaveFactoryStore, WEAVE_BIN_FILE_NAME, WEAVE_BIN_FILE_CONTENTS),
            (
                ServiceMarkers::WidevineFactoryStore,
                WIDEVINE_BIN_FILE_NAME,
                WIDEVINE_BIN_FILE_CONTENTS,
            ),
        ] {
            let out = get_factory_store_output(
                &realm,
                marker,
                FactoryStoreCmd::Dump { name: name.to_string() },
            )
            .await?;
            assert_eq!(out.len(), 1);
            assert!(out[0].contains("00000000"));
            assert!(out[0].contains(&contents.to_hex(HEX_DISPLAY_CHUNK_SIZE)));
        }
        Ok(())
    }

    #[fasync::run_singlethreaded(test)]
    async fn dump_factory_item() -> Result<(), Error> {
        let realm = build_realm().await?;
        let out = get_factory_items_output(&realm, FactoryItemsCmd::Dump { extra: 0 }).await?;
        assert_eq!(out.len(), 2);
        assert!(out[0].contains("00000000"));
        assert!(out[0].contains(&FACTORY_ITEM_CONTENTS.to_hex(HEX_DISPLAY_CHUNK_SIZE)));
        assert!(out[1].contains("Length=4"));
        Ok(())
    }
}
