// 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 {
    crate::model::events::{event::Event, registry::ComponentEventRoute, stream::EventStream},
    async_utils::stream::FlattenUnorderedExt,
    cm_rust::{ChildRef, EventScope},
    cm_types::{LongName, Name},
    cm_util::io::clone_dir,
    fidl::endpoints::Proxy,
    fidl_fuchsia_component as fcomponent, fidl_fuchsia_io as fio,
    fuchsia_zircon::{
        self as zx, sys::ZX_CHANNEL_MAX_MSG_BYTES, sys::ZX_CHANNEL_MAX_MSG_HANDLES, HandleBased,
    },
    futures::{stream, stream::Peekable, Stream, StreamExt},
    hooks::{CapabilityReceiver, EventPayload, EventType, HasEventType},
    measure_tape_for_events::Measurable,
    moniker::{ChildNameBase, ExtendedMoniker, Moniker, MonikerBase},
    std::{pin::Pin, sync::Arc, task::Poll},
    tracing::{error, warn},
};

// Number of bytes the header of a vector occupies in a fidl message.
// TODO(https://fxbug.dev/42181010): This should be a constant in a FIDL library.
const FIDL_VECTOR_HEADER_BYTES: usize = 16;

// Number of bytes the header of a fidl message occupies.
// TODO(https://fxbug.dev/42181010): This should be a constant in a FIDL library.
const FIDL_HEADER_BYTES: usize = 16;

/// Computes the scope length, which is the number of segments
/// up until the first scope. This is used to re-map the moniker
/// of an event before passing it off to the component that is
/// reading the event stream.
fn get_scope_length(route: &[ComponentEventRoute]) -> usize {
    // Length is the length of the scope (0 if no scope, 1 for the
    // component after <root>)
    let mut length = 0;
    // Index is the current index in route +1 (since we want to exclude
    // a component's parent from the moniker).
    let mut index = 1;
    for component in route {
        // Set length to index, this is the most recent
        // scope found in the route.
        if component.scope.is_some() {
            length = index;
        }
        index += 1;
    }
    length
}

/// Determines if an event from a specified moniker
/// may be routed to a given scope.
fn is_moniker_valid_within_scope(moniker: &ExtendedMoniker, route: &[ComponentEventRoute]) -> bool {
    match moniker {
        ExtendedMoniker::ComponentInstance(instance) => {
            validate_component_instance(instance, route.iter())
        }
        ExtendedMoniker::ComponentManager => false,
    }
}

// Returns true if the filter contains a specific Ref
fn event_filter_contains_ref(
    filter: &Option<Vec<EventScope>>,
    name: &LongName,
    collection: Option<&Name>,
) -> bool {
    filter.as_ref().map_or(true, |value| {
        value
            .iter()
            .map(|value| match value {
                EventScope::Child(ChildRef { collection: child_coll, name: child_name }) => {
                    collection == child_coll.as_ref() && child_name == name
                }
                EventScope::Collection(collection_name) => Some(collection_name) == collection,
            })
            .any(|val| val)
    })
}

/// Checks the specified instance against the specified route,
/// Returns Some(true) if the route is explicitly allowed,
/// Some(false) if the route is explicitly rejected,
/// or None if allowed because no route explicitly rejected it.
fn validate_component_instance(
    instance: &Moniker,
    mut iter: std::slice::Iter<'_, ComponentEventRoute>,
) -> bool {
    let path = instance.path();
    let mut event_iter = path.iter();
    // Component manager is an unnamed component which exists in route
    // but not in the moniker (because it's not a named component).
    // We take the first item from the iterator and get its scope
    // to determine initial scoping and ensure that route
    // and moniker are properly aligned to each other.
    let mut active_scope = iter.next().unwrap().scope.clone();
    for component in iter {
        if let Some(event_part) = event_iter.next() {
            if !event_filter_contains_ref(&active_scope, event_part.name(), event_part.collection())
            {
                // Reject due to scope mismatch
                return false;
            }
            let child_ref = ChildRef {
                name: event_part.name().clone(),
                collection: event_part.collection().cloned(),
            };
            if Some(child_ref) != component.component {
                // Reject due to path mismatch
                return false;
            }
            active_scope = component.scope.clone();
        } else {
            // Reject due to no more event parts
            return false;
        }
    }
    match (active_scope, event_iter.next()) {
        (Some(scopes), Some(event)) => {
            if !event_filter_contains_ref(&Some(scopes), event.name(), event.collection.as_ref()) {
                return false;
            }
        }
        (Some(_), None) => {
            // Reject due to no more event parts
            return false;
        }
        _ => {}
    }
    // Reached end of scope.
    true
}

/// Filters and downscopes an event by a route.
/// Returns true if the event is allowed given the specified route,
/// false otherwise.
fn filter_event(moniker: &mut ExtendedMoniker, route: &[ComponentEventRoute]) -> bool {
    let scope_length = get_scope_length(route);
    if !is_moniker_valid_within_scope(&moniker, &route[0..scope_length]) {
        return false;
    }
    // For scoped events, the apparent root (visible to the component)
    // starts at the last scope declaration which applies to this particular event.
    // Since this creates a relative rather than absolute moniker, where the base may be different
    // for each event, ambiguous component monikers are possible here.
    if let ExtendedMoniker::ComponentInstance(instance) = moniker {
        let mut path = instance.path().clone();
        path.reverse();
        for _ in 0..scope_length {
            path.pop();
        }
        path.reverse();
        *instance = Moniker::new(path);
    }
    true
}

/// Validates and filters an event, returning true if the route is allowed,
/// false otherwise. The scope of the event is filtered to the allowed route.
pub fn validate_and_filter_event(
    moniker: &mut ExtendedMoniker,
    route: &[ComponentEventRoute],
) -> bool {
    let needs_filter = route.iter().any(|component| component.scope.is_some());
    if needs_filter {
        filter_event(moniker, route)
    } else {
        true
    }
}

/// [`EventFiller`] helps build a vector of events up to the Zircon
/// channel message size limit.
///
/// TODO(https://fxbug.dev/42181010): This can be simplified given better
/// FIDL large messages support.
struct EventFiller {
    bytes_used: usize,
    handles_used: usize,
    events: Vec<fcomponent::Event>,
}

impl EventFiller {
    fn new() -> Self {
        EventFiller {
            bytes_used: FIDL_HEADER_BYTES + FIDL_VECTOR_HEADER_BYTES,
            handles_used: 0,
            events: vec![],
        }
    }

    fn is_empty(&self) -> bool {
        self.events.is_empty()
    }

    /// Measures the size of an event, increments bytes used, and returns the
    /// event Vec as an error if full.
    ///
    /// If there isn't enough space for even one event, logs an error and
    /// returns an empty Vec.
    fn add_event(
        mut self,
        event: fcomponent::Event,
        pending_event: &mut Option<fcomponent::Event>,
    ) -> Result<Self, Vec<fcomponent::Event>> {
        let event_type = event
            .header
            .as_ref()
            .map(|header| format!("{:?}", header.event_type))
            .unwrap_or("unknown".to_string());
        let measure_tape = event.measure();
        self.bytes_used += measure_tape.num_bytes;
        self.handles_used += measure_tape.num_handles;
        if self.bytes_used > ZX_CHANNEL_MAX_MSG_BYTES as usize
            || self.handles_used > ZX_CHANNEL_MAX_MSG_HANDLES as usize
        {
            if pending_event.is_some() {
                unreachable!("Overflowed twice");
            }
            *pending_event = Some(event);
            if self.events.len() == 0 {
                error!(
                    event_type = event_type.as_str(),
                    "Event exceeded the maximum channel size, dropping event"
                );
            }
            return Err(self.events);
        } else {
            self.events.push(event);
            return Ok(self);
        }
    }
}

impl From<EventFiller> for Vec<fcomponent::Event> {
    fn from(value: EventFiller) -> Self {
        value.events
    }
}

/// This function returns events via both `Ok` and `Err` such that we
/// may use the question mark operator to return early.
async fn do_handle_get_next_request(
    mut event_stream: Pin<&mut Peekable<impl Stream<Item = fcomponent::Event>>>,
    pending_event: &mut Option<fcomponent::Event>,
) -> Result<Vec<fcomponent::Event>, Vec<fcomponent::Event>> {
    let mut events = EventFiller::new();

    // Read overflowed events from the buffer first.
    if let Some(event) = pending_event.take() {
        events = events.add_event(event, pending_event)?;
    }

    if events.is_empty() {
        // Block one time, to ensure we get at least one event to return to the client.
        if let Some(event) = event_stream.next().await {
            events = events.add_event(event, pending_event)?;
        }
    }
    loop {
        // Try to add any immediately available event, stopping if there aren't any.
        let Poll::Ready(_) = futures::poll!(event_stream.as_mut().peek()) else {
            break;
        };
        let Some(event) = event_stream.next().await else {
            break;
        };
        events = events.add_event(event, pending_event)?;
    }
    if events.is_empty() {
        unreachable!("Internal: The event_stream internal channel should never be closed.");
    }
    Ok(events.into())
}

/// Obtains the next batch of events, waiting for at least one. Returns when there are no
/// more events available at the moment, or when the events are going to exceed the
/// maximum size that can be sent in a channel message.
async fn handle_get_next_request(
    event_stream: Pin<&mut Peekable<impl Stream<Item = fcomponent::Event>>>,
    pending_event: &mut Option<fcomponent::Event>,
) -> Vec<fcomponent::Event> {
    match do_handle_get_next_request(event_stream, pending_event).await {
        Ok(v) => v,
        Err(v) => v,
    }
}

/// Serves the event_stream protocol implemented for EventStreamRequestStream
/// This is needed because we get the request stream directly as a stream from FDIO
/// but as a ServerEnd from the hooks system.
pub async fn serve_event_stream(
    event_stream: EventStream,
    mut stream: fcomponent::EventStreamRequestStream,
) {
    async fn filter_event(input: (Event, Option<Vec<ComponentEventRoute>>)) -> Option<Event> {
        let (mut event, route) = input;
        if let Some(mut route) = route {
            route.reverse();
            if !validate_and_filter_event(&mut event.event.target_moniker, &route) {
                return None;
            }
        }
        Some(event)
    }
    async fn filter_log_errors(
        result: Result<fcomponent::Event, anyhow::Error>,
    ) -> Option<fcomponent::Event> {
        match result {
            Ok(event_fidl_object) => Some(event_fidl_object),
            Err(error) => {
                warn!(?error, "Failed to create event object");
                None
            }
        }
    }
    let event_stream = event_stream
        .filter_map(filter_event)
        .map(create_event_fidl_objects)
        .fuse()
        .flatten_unordered()
        .filter_map(filter_log_errors);
    let event_stream = event_stream.boxed().peekable();
    let mut event_stream = std::pin::pin!(event_stream);

    let mut buffer = None;
    while let Some(Ok(request)) = stream.next().await {
        match request {
            fcomponent::EventStreamRequest::GetNext { responder } => {
                let events = handle_get_next_request(event_stream.as_mut(), &mut buffer).await;
                if !responder.send(events).is_ok() {
                    // Close the channel if an error occurs while handling the request.
                    return;
                }
            }
            fcomponent::EventStreamRequest::WaitForReady { responder } => {
                let _ = responder.send();
            }
        }
    }
}

type BoxStream<T> = Pin<Box<dyn Stream<Item = T> + Send + 'static>>;

fn stream_once<T: Send + 'static>(value: T) -> BoxStream<T> {
    stream::once(std::future::ready(value)).boxed()
}

fn create_event_payloads(
    event_payload: &EventPayload,
) -> BoxStream<Result<fcomponent::EventPayload, fidl::Error>> {
    match event_payload {
        EventPayload::CapabilityRequested { name, receiver, .. } => {
            create_capability_requested_payload(name.to_string(), receiver.clone())
        }
        EventPayload::Stopped { status, .. } => {
            stream_once(Ok(fcomponent::EventPayload::Stopped(fcomponent::StoppedPayload {
                status: Some(status.into_raw()),
                ..Default::default()
            })))
        }
        EventPayload::DebugStarted { runtime_dir, break_on_start } => {
            stream_once(Ok(create_debug_started_payload(runtime_dir, break_on_start)))
        }
        payload => stream_once(Ok(match payload.event_type() {
            EventType::Discovered => {
                fcomponent::EventPayload::Discovered(fcomponent::DiscoveredPayload::default())
            }
            EventType::Destroyed => {
                fcomponent::EventPayload::Destroyed(fcomponent::DestroyedPayload::default())
            }
            EventType::Resolved => {
                fcomponent::EventPayload::Resolved(fcomponent::ResolvedPayload::default())
            }
            EventType::Unresolved => {
                fcomponent::EventPayload::Unresolved(fcomponent::UnresolvedPayload::default())
            }
            EventType::Started => {
                fcomponent::EventPayload::Started(fcomponent::StartedPayload::default())
            }
            _ => unreachable!("Unsupported event type"),
        })),
    }
}

fn create_capability_requested_payload(
    name: String,
    receiver: CapabilityReceiver,
) -> BoxStream<Result<fcomponent::EventPayload, fidl::Error>> {
    match receiver.take() {
        // If this component has the opportunity to intercept capability requests,
        // emit a CapabilityRequested event for every request it receives.
        Some(receiver) => stream::unfold(receiver, move |receiver| {
            let name = name.clone();
            async move {
                let Some(message) = receiver.receive().await else {
                    return None;
                };
                let payload = fcomponent::CapabilityRequestedPayload {
                    name: Some(name),
                    capability: Some(message.channel),
                    ..Default::default()
                };
                Some((Ok(fcomponent::EventPayload::CapabilityRequested(payload)), receiver))
            }
        })
        .boxed(),
        // If someone else took away the opportunity to intercept capability requests,
        // emit a CapabilityRequested event with an absent capability.
        None => stream::once(std::future::ready(Ok(
            fcomponent::EventPayload::CapabilityRequested(fcomponent::CapabilityRequestedPayload {
                name: Some(name),
                capability: None,
                ..Default::default()
            }),
        )))
        .boxed(),
    }
}

fn create_debug_started_payload(
    runtime_dir: &Option<fio::DirectoryProxy>,
    break_on_start: &Arc<zx::EventPair>,
) -> fcomponent::EventPayload {
    fcomponent::EventPayload::DebugStarted(fcomponent::DebugStartedPayload {
        runtime_dir: clone_dir(runtime_dir.as_ref()).map(|dir| {
            dir.into_channel()
                .expect("could not convert directory to channel")
                .into_zx_channel()
                .into()
        }),
        break_on_start: break_on_start.duplicate_handle(zx::Rights::SAME_RIGHTS).ok(),
        ..Default::default()
    })
}

/// Creates a stream of FIDL Event objects from an Event.
fn create_event_fidl_objects(event: Event) -> BoxStream<Result<fcomponent::Event, anyhow::Error>> {
    let moniker_string = match (&event.event.target_moniker, &event.scope_moniker) {
        (moniker @ ExtendedMoniker::ComponentManager, _) => moniker.to_string(),
        (ExtendedMoniker::ComponentInstance(target), ExtendedMoniker::ComponentManager) => {
            target.to_string()
        }
        (ExtendedMoniker::ComponentInstance(target), ExtendedMoniker::ComponentInstance(scope)) => {
            target.strip_prefix(scope).expect("target must be a child of event scope").to_string()
        }
    };
    let event_type = match event.event.event_type().try_into() {
        Ok(event_type) => event_type,
        Err(error) => return stream::once(std::future::ready(Err(error))).boxed(),
    };
    let header = fcomponent::EventHeader {
        event_type: Some(event_type),
        moniker: Some(moniker_string),
        component_url: Some(event.event.component_url.to_string()),
        timestamp: Some(event.event.timestamp.into_nanos()),
        ..Default::default()
    };
    let payload_stream = create_event_payloads(&event.event.payload);
    payload_stream
        .map(move |payload| {
            payload
                .and_then(|payload| {
                    Ok(fcomponent::Event {
                        header: Some(header.clone()),
                        payload: Some(payload),
                        ..Default::default()
                    })
                })
                .map_err(Into::into)
        })
        .boxed()
}

#[cfg(test)]
mod tests {
    use crate::model::events::serve::validate_and_filter_event;
    use crate::model::events::serve::ComponentEventRoute;
    use cm_rust::ChildRef;
    use cm_rust::EventScope;
    use moniker::ChildName;
    use moniker::ExtendedMoniker;
    use moniker::Moniker;
    use moniker::MonikerBase;

    // Route: /root(coll)
    // Event: /root
    // Output: (rejected)
    #[test]
    fn test_validate_and_filter_event_at_root() {
        let mut moniker =
            ExtendedMoniker::ComponentInstance(Moniker::new(vec![ChildName::try_new(
                "root",
                Some("coll"),
            )
            .unwrap()]));
        let route = vec![
            ComponentEventRoute { component: None, scope: None },
            ComponentEventRoute {
                component: Some(ChildRef { name: "root".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Collection("coll".parse().unwrap())]),
            },
        ];
        assert!(!validate_and_filter_event(&mut moniker, &route));
    }

    // Route: /<root>/core(test_manager)/test_manager
    // Event: /
    // Output: (rejected)
    #[test]
    fn test_validate_and_filter_event_empty_moniker() {
        let mut event = ExtendedMoniker::ComponentInstance(Moniker::root());
        let route = vec![
            ComponentEventRoute { component: None, scope: None },
            ComponentEventRoute {
                component: Some(ChildRef { name: "core".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Collection("test_manager".parse().unwrap())]),
            },
            ComponentEventRoute {
                component: Some(ChildRef {
                    name: "test_manager".parse().unwrap(),
                    collection: None,
                }),
                scope: None,
            },
        ];
        assert_eq!(validate_and_filter_event(&mut event, &route), false);
    }

    // Route: a(b)/b(c)/c
    // Event: a/b/c
    // Output: /
    #[test]
    fn test_validate_and_filter_event_moniker_root() {
        let mut event = ExtendedMoniker::ComponentInstance(Moniker::new(vec![
            ChildName::try_new("a", None).unwrap(),
            ChildName::try_new("b", None).unwrap(),
            ChildName::try_new("c", None).unwrap(),
        ]));
        let route = vec![
            ComponentEventRoute { component: None, scope: None },
            ComponentEventRoute {
                component: Some(ChildRef { name: "a".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Child(ChildRef {
                    name: "b".parse().unwrap(),
                    collection: None,
                })]),
            },
            ComponentEventRoute {
                component: Some(ChildRef { name: "b".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Child(ChildRef {
                    name: "c".parse().unwrap(),
                    collection: None,
                })]),
            },
            ComponentEventRoute {
                component: Some(ChildRef { name: "c".parse().unwrap(), collection: None }),
                scope: None,
            },
        ];
        assert!(super::validate_and_filter_event(&mut event, &route));
        assert_eq!(event, ExtendedMoniker::ComponentInstance(Moniker::root()));
    }

    // Route: a(b)/b(c)/c
    // Event: a/b/c/d
    // Output: d
    #[test]
    fn test_validate_and_filter_event_moniker_children_scoped() {
        let mut event = ExtendedMoniker::ComponentInstance(Moniker::new(vec![
            ChildName::try_new("a", None).unwrap(),
            ChildName::try_new("b", None).unwrap(),
            ChildName::try_new("c", None).unwrap(),
            ChildName::try_new("d", None).unwrap(),
        ]));
        let route = vec![
            ComponentEventRoute { component: None, scope: None },
            ComponentEventRoute {
                component: Some(ChildRef { name: "a".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Child(ChildRef {
                    name: "b".parse().unwrap(),
                    collection: None,
                })]),
            },
            ComponentEventRoute {
                component: Some(ChildRef { name: "b".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Child(ChildRef {
                    name: "c".parse().unwrap(),
                    collection: None,
                })]),
            },
            ComponentEventRoute {
                component: Some(ChildRef { name: "c".parse().unwrap(), collection: None }),
                scope: None,
            },
        ];
        assert!(super::validate_and_filter_event(&mut event, &route));
        assert_eq!(
            event,
            ExtendedMoniker::ComponentInstance(Moniker::new(vec![
                ChildName::try_new("d", None).unwrap()
            ]))
        );
    }

    // Route: a(b)/b(c)/c
    // Event: a
    // Output: (rejected)
    #[test]
    fn test_validate_and_filter_event_moniker_above_root_rejected() {
        let mut event =
            ExtendedMoniker::ComponentInstance(Moniker::new(vec![
                ChildName::try_new("a", None).unwrap()
            ]));
        let route = vec![
            ComponentEventRoute { component: None, scope: None },
            ComponentEventRoute {
                component: Some(ChildRef { name: "a".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Collection("b".parse().unwrap())]),
            },
            ComponentEventRoute {
                component: Some(ChildRef { name: "b".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Collection("c".parse().unwrap())]),
            },
            ComponentEventRoute {
                component: Some(ChildRef { name: "c".parse().unwrap(), collection: None }),
                scope: None,
            },
        ];
        assert!(!super::validate_and_filter_event(&mut event, &route));
        assert_eq!(
            event,
            ExtendedMoniker::ComponentInstance(Moniker::new(vec![
                ChildName::try_new("a", None).unwrap()
            ]))
        );
    }

    // Route: a/b(c)/c
    // Event: f/i
    // Output: (rejected)
    #[test]
    fn test_validate_and_filter_event_moniker_ambiguous() {
        let mut event = ExtendedMoniker::ComponentInstance(Moniker::new(vec![
            ChildName::try_new("f", None).unwrap(),
            ChildName::try_new("i", None).unwrap(),
        ]));
        let route = vec![
            ComponentEventRoute { component: None, scope: None },
            ComponentEventRoute {
                component: Some(ChildRef { name: "a".parse().unwrap(), collection: None }),
                scope: None,
            },
            ComponentEventRoute {
                component: Some(ChildRef { name: "b".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Collection("c".parse().unwrap())]),
            },
            ComponentEventRoute {
                component: Some(ChildRef { name: "c".parse().unwrap(), collection: None }),
                scope: None,
            },
        ];
        assert!(!super::validate_and_filter_event(&mut event, &route));
    }

    // Route: /core(test_manager)/test_manager/test-id(test_wrapper)/test_wrapper(test_root)
    // Event: /core/feedback
    // Output: (rejected)
    #[test]
    fn test_validate_and_filter_event_moniker_root_rejected() {
        let mut event = ExtendedMoniker::ComponentInstance(Moniker::new(vec![
            ChildName::try_new("core", None).unwrap(),
            ChildName::try_new("feedback", None).unwrap(),
        ]));
        let route = vec![
            ComponentEventRoute { component: None, scope: None },
            ComponentEventRoute {
                component: Some(ChildRef { name: "core".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Collection("test_manager".parse().unwrap())]),
            },
            ComponentEventRoute {
                component: Some(ChildRef {
                    name: "test_manager".parse().unwrap(),
                    collection: None,
                }),
                scope: Some(vec![EventScope::Collection("test_wrapper".parse().unwrap())]),
            },
            ComponentEventRoute {
                component: Some(ChildRef {
                    name: "test_wrapper".parse().unwrap(),
                    collection: None,
                }),
                scope: Some(vec![EventScope::Collection("test_root".parse().unwrap())]),
            },
        ];
        assert_eq!(super::validate_and_filter_event(&mut event, &route), false);
    }

    // Route: /<root>/core(test_manager)/test_manager(col(tests))/auto-3fc01a79864c741:tests(test_wrapper)/test_wrapper(col(test),enclosing_env,hermetic_resolver)/test:test_root/archivist
    // Event: /core/test_manager/tests:auto-3fc01a79864c741/test_wrapper/archivist
    // Output: (rejected)
    #[test]
    fn test_validate_child_under_scoped_collection_is_root() {
        let mut event = ExtendedMoniker::ComponentInstance(Moniker::new(vec![
            ChildName::try_new("core", None).unwrap(),
            ChildName::try_new("test_manager", None).unwrap(),
            ChildName::try_new("auto-3fc01a79864c741", Some("tests")).unwrap(),
            ChildName::try_new("test_wrapper", None).unwrap(),
            ChildName::try_new("archivist", None).unwrap(),
        ]));
        let route = vec![
            ComponentEventRoute { component: None, scope: None },
            ComponentEventRoute {
                component: Some(ChildRef { name: "core".parse().unwrap(), collection: None }),
                scope: Some(vec![EventScope::Child(ChildRef {
                    name: "test_manager".parse().unwrap(),
                    collection: None,
                })]),
            },
            ComponentEventRoute {
                component: Some(ChildRef {
                    name: "test_manager".parse().unwrap(),
                    collection: None,
                }),
                scope: Some(vec![EventScope::Collection("tests".parse().unwrap())]),
            },
            ComponentEventRoute {
                component: Some(ChildRef {
                    name: "auto-3fc01a79864c741".parse().unwrap(),
                    collection: Some("tests".parse().unwrap()),
                }),
                scope: Some(vec![EventScope::Child(ChildRef {
                    name: "test_wrapper".parse().unwrap(),
                    collection: None,
                })]),
            },
            ComponentEventRoute {
                component: Some(ChildRef {
                    name: "test_wrapper".parse().unwrap(),
                    collection: None,
                }),
                scope: Some(vec![
                    EventScope::Collection("test".parse().unwrap()),
                    EventScope::Child(ChildRef {
                        name: "enclosing_env".parse().unwrap(),
                        collection: None,
                    }),
                    EventScope::Child(ChildRef {
                        name: "hermetic_resolver".parse().unwrap(),
                        collection: None,
                    }),
                ]),
            },
            ComponentEventRoute {
                component: Some(ChildRef {
                    name: "test_root".parse().unwrap(),
                    collection: Some("test".parse().unwrap()),
                }),
                scope: None,
            },
        ];
        assert_eq!(super::validate_and_filter_event(&mut event, &route), false);
    }
}
