// Copyright 2018 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::{Context as _, Error},
    fidl_fuchsia_sys::{ComponentControllerEvent, EnvironmentOptions, TerminationReason},
    fidl_fuchsia_test_echos::{
        EchoExposedByParentRequest, EchoExposedByParentRequestStream, EchoExposedBySiblingMarker,
        EchoHiddenByParentRequest, EchoHiddenByParentRequestStream,
    },
    fuchsia_async as fasync,
    fuchsia_component::{
        client::AppBuilder, fuchsia_single_component_package_url, server::ServiceFs,
    },
    futures::prelude::*,
};

fn echo_exposed_server(stream: EchoExposedByParentRequestStream) -> impl Future<Output = ()> {
    stream
        .err_into::<anyhow::Error>()
        .try_for_each(|EchoExposedByParentRequest::Echo { value, responder }| async move {
            responder.send(value).context("sending response")?;
            Ok(())
        })
        .unwrap_or_else(|e: anyhow::Error| panic!("error running echo server: {:?}", e))
}

fn echo_hidden_server(stream: EchoHiddenByParentRequestStream) -> impl Future<Output = ()> {
    stream
        .err_into::<anyhow::Error>()
        .try_for_each(|EchoHiddenByParentRequest::Echo { value, responder }| async move {
            responder.send(value).context("sending response")?;
            Ok(())
        })
        .unwrap_or_else(|e: anyhow::Error| panic!("error running echo server: {:?}", e))
}

const CHILD_SIBLING_URL: &str =
    fuchsia_single_component_package_url!("fuchsia_component_test_middle_sibling");
const CHILD_URL: &str = fuchsia_single_component_package_url!("fuchsia_component_test_middle");
const ENV_NAME: &str = "fuchsia_component_middle_test_environment";

enum Services {
    Exposed(EchoExposedByParentRequestStream),
    Hidden(EchoHiddenByParentRequestStream),
}

#[fasync::run_singlethreaded]
async fn main() -> Result<(), Error> {
    println!("connecting to {}", CHILD_URL);
    let mut sibling = AppBuilder::new(CHILD_SIBLING_URL);

    let mut fs = ServiceFs::new();
    fs.add_fidl_service(Services::Exposed)
        .add_fidl_service(Services::Hidden)
        .add_proxy_service_to::<EchoExposedBySiblingMarker, _>(sibling.directory_request()?.clone());

    let options = EnvironmentOptions {
        inherit_parent_services: false,
        use_parent_runners: false,
        kill_on_oom: false,
        delete_storage_on_death: false,
    };
    let env = fs.create_nested_environment_with_options(ENV_NAME, options)?;

    // spawn the child components within the newly created environment
    let sibling = sibling.spawn(env.launcher())?;
    let child_app = AppBuilder::new(CHILD_URL).spawn(env.launcher())?;

    // spawn server to respond to child component requests
    fasync::Task::spawn(fs.for_each_concurrent(None, |req| async {
        match req {
            Services::Exposed(stream) => echo_exposed_server(stream).await,
            Services::Hidden(stream) => echo_hidden_server(stream).await,
        }
    }))
    .detach();

    // verify sibling is running by connecting directly to its service
    let multiply_by_two = sibling.connect_to_service::<EchoExposedBySiblingMarker>()?;
    assert_eq!(14, multiply_by_two.echo(7).await?);

    // verify sibling is running by connecting to its service through the nested environment
    let multiply_by_two = env.connect_to_service::<EchoExposedBySiblingMarker>()?;
    assert_eq!(14, multiply_by_two.echo(7).await?);

    // wait for middle component to exit
    let mut component_stream = child_app.controller().take_event_stream();
    match component_stream
        .next()
        .await
        .expect("component event stream ended before termination event")?
    {
        ComponentControllerEvent::OnDirectoryReady {} => {
            panic!("middle component unexpectedly exposed a directory")
        }
        ComponentControllerEvent::OnTerminated {
            return_code: 0,
            termination_reason: TerminationReason::Exited,
        } => {}
        ComponentControllerEvent::OnTerminated { return_code, termination_reason } => {
            panic!("Unexpected exit condition: {:?}", (return_code, termination_reason))
        }
    }

    Ok(())
}
