// 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::Error,
    component_events::{
        events::{
            self as events, CapabilityRequested, Event, EventSource, EventStream, EventStreamError,
            EventSubscription,
        },
        matcher::EventMatcher,
        sequence::EventSequence,
    },
    fidl_fidl_test_components as test_protocol, fuchsia_async as fasync,
    fuchsia_component_test::ScopedInstance,
    futures_util::stream::TryStreamExt,
    std::sync::{Arc, Mutex},
    tracing::info,
};

#[fuchsia::test]
async fn test_exit_detection() {
    let event_source = EventSource::new().unwrap();
    let event_stream = event_source
        .subscribe(vec![EventSubscription::new(vec![events::Stopped::NAME])])
        .await
        .unwrap();

    let collection_name = String::from("test-collection");

    let instance = ScopedInstance::new(
        collection_name.clone(),
        String::from(
            "fuchsia-pkg://fuchsia.com/elf_runner_lifecycle_test#meta/immediate_exit_component.cm",
        ),
    )
    .await
    .unwrap();

    instance.connect_to_binder().unwrap();

    let target_moniker = format!("./{}:{}", collection_name, instance.child_name());

    EventSequence::new()
        .then(EventMatcher::ok().r#type(events::Stopped::TYPE).moniker(&target_moniker))
        .expect(event_stream)
        .await
        .unwrap();
}

#[fuchsia::test]
async fn test_exit_after_rendezvous() {
    // Get the event source, install our service injector, and then start the
    // component tree.
    let event_source = EventSource::new().unwrap();
    let mut event_stream = event_source
        .subscribe(vec![EventSubscription::new(vec![events::Started::NAME, events::Stopped::NAME])])
        .await
        .unwrap();

    // tests don't have access to output directory so using capability requested event to offer a
    // protocol.
    let capability_requested_event_stream =
        event_source.take_static_event_stream("EventStream").await.unwrap();
    let rendezvous_service = RendezvousService::new(capability_requested_event_stream);

    // Launch the component under test.
    let collection_name = String::from("test-collection");
    let instance = ScopedInstance::new(
        collection_name.clone(),
        String::from(
            "fuchsia-pkg://fuchsia.com/elf_runner_lifecycle_test#meta/rendezvous_exit_component.cm",
        ),
    )
    .await
    .unwrap();

    instance.connect_to_binder().unwrap();

    let target_moniker = format!("./{}:{}", collection_name, instance.child_name());

    // First, ensure that component has started.
    EventMatcher::ok()
        .moniker(&target_moniker)
        .wait::<events::Started>(&mut event_stream)
        .await
        .expect("failed to observe events");

    // Then, wait to get confirmation that the component under test exited.
    EventSequence::new()
        .then(EventMatcher::ok().r#type(events::Stopped::TYPE).moniker(&target_moniker))
        .expect(event_stream)
        .await
        .unwrap();

    // Check that we received a request from the component under test.
    assert_eq!(*rendezvous_service.call_count.lock().unwrap(), 1);
}

struct RendezvousService {
    call_count: Mutex<u32>,
}

impl RendezvousService {
    // Right now we are using simple event stream. If this is used by multiple tests cases,
    // this struct should use mock component from RealmBuilder.
    fn new(mut event_stream: EventStream) -> Arc<Self> {
        let obj = Arc::new(RendezvousService { call_count: Mutex::new(0) });
        let obj_clone = obj.clone();
        fasync::Task::spawn(async move {
            loop {
                let mut event =
                    match EventMatcher::ok().wait::<CapabilityRequested>(&mut event_stream).await {
                        Ok(e) => e,
                        Err(e) => match e.downcast::<EventStreamError>() {
                            Ok(EventStreamError::StreamClosed) => return,
                            Err(e) => panic!("Unknown error! {:?}", e),
                        },
                    };

                let stream: test_protocol::TriggerRequestStream =
                    event.take_capability::<test_protocol::TriggerMarker>().unwrap();
                obj_clone.clone().serve(stream).await.expect("error serving trigger");
            }
        })
        .detach();
        obj
    }

    async fn serve(
        self: Arc<Self>,
        mut stream: test_protocol::TriggerRequestStream,
    ) -> Result<(), Error> {
        while let Some(request) = stream.try_next().await.unwrap() {
            match request {
                test_protocol::TriggerRequest::Run { responder } => {
                    {
                        let mut count = self.call_count.lock().unwrap();
                        *count += 1;
                    }
                    info!("Received rendezvous from target");
                    responder.send("").unwrap();
                }
            }
        }
        Ok(())
    }
}
