// 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.

#![feature(async_await, await_macro)]

use {
    crate::module_output::ModuleOutputWriterService,
    crate::story_context_store::StoryContextStore,
    failure::{Error, ResultExt},
    fidl_fuchsia_app_discover::{DiscoverRegistryRequest, DiscoverRegistryRequestStream},
    fuchsia_async as fasync,
    fuchsia_component::server::ServiceFs,
    fuchsia_syslog as syslog,
    futures::prelude::*,
    parking_lot::Mutex,
    std::sync::Arc,
};

mod module_output;
mod story_context_store;
mod utils;

// The directory name where the discovermgr FIDL services are exposed.
static SERVICE_DIRECTORY: &str = "public";

enum IncomingServices {
    DiscoverRegistry(DiscoverRegistryRequestStream),
    // TODO(miguelfrde): add additional services
}

/// Handle DiscoveryRegistry requests.
async fn run_discover_registry_server(
    story_context_store: Arc<Mutex<StoryContextStore>>,
    mut stream: DiscoverRegistryRequestStream,
) -> Result<(), Error> {
    while let Some(request) =
        await!(stream.try_next()).context("Error running discover registry")?
    {
        match request {
            DiscoverRegistryRequest::RegisterModuleOutputWriter { module, request, .. } => {
                let module_output_stream = request.into_stream()?;
                ModuleOutputWriterService::new(story_context_store.clone(), module)?
                    .spawn(module_output_stream);
            }
        }
    }
    Ok(())
}

#[fasync::run_singlethreaded]
async fn main() -> Result<(), Error> {
    syslog::init_with_tags(&["discovermgr"])?;

    let story_context_store = Arc::new(Mutex::new(StoryContextStore::new()));

    let mut fs = ServiceFs::new_local();
    fs.dir(SERVICE_DIRECTORY).add_fidl_service(IncomingServices::DiscoverRegistry);

    fs.take_and_serve_directory_handle()?;

    const MAX_CONCURRENT: usize = 10_000;
    let fut =
        fs.for_each_concurrent(MAX_CONCURRENT, |IncomingServices::DiscoverRegistry(stream)| {
            run_discover_registry_server(story_context_store.clone(), stream)
                .unwrap_or_else(|e| syslog::fx_log_err!("{:?}", e))
        });

    await!(fut);
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use failure::ResultExt;
    use fidl_fuchsia_app_discover::{
        DiscoverRegistryMarker, ModuleIdentifier, ModuleOutputWriterMarker,
    };
    use fuchsia_component::client;

    static COMPONENT_URL: &str = "fuchsia-pkg://fuchsia.com/discovermgr#meta/discovermgr.cmx";

    #[fasync::run_singlethreaded(test)]
    async fn test_module_output() -> Result<(), Error> {
        let launcher = client::launcher().context("Failed to open launcher service")?;
        let app = client::launch(&launcher, COMPONENT_URL.to_string(), None /* arguments */)
            .context("Failed to launch discovermgr")?;
        let discover_manager = app
            .connect_to_service::<DiscoverRegistryMarker>()
            .context("Failed to connect to DiscoverRegistry")?;

        let mod_scope = ModuleIdentifier {
            story_id: Some("test-story".to_string()),
            module_path: Some(vec!["test-mod".to_string()]),
        };
        let (module_output_proxy, server_end) =
            fidl::endpoints::create_proxy::<ModuleOutputWriterMarker>()?;
        assert!(discover_manager.register_module_output_writer(mod_scope, server_end).is_ok());

        let result = await!(module_output_proxy.write("test-param", Some("test-ref")))?;
        assert!(result.is_ok());
        Ok(())
    }
}
