// 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::{
        consumer_controls_binding, keyboard_binding, light_sensor_binding, metrics, mouse_binding,
        touch_binding,
    },
    anyhow::{format_err, Error},
    async_trait::async_trait,
    async_utils::hanging_get::client::HangingGetStream,
    fidl::endpoints::Proxy,
    fidl_fuchsia_input_report as fidl_input_report,
    fidl_fuchsia_input_report::{InputDeviceMarker, InputReport},
    fidl_fuchsia_io as fio, fuchsia_async as fasync,
    fuchsia_inspect::health::Reporter,
    fuchsia_inspect::{
        ExponentialHistogramParams, HistogramProperty as _, NumericProperty, Property,
    },
    fuchsia_trace as ftrace, fuchsia_zircon as zx,
    futures::{
        channel::mpsc::{UnboundedReceiver, UnboundedSender},
        stream::StreamExt,
    },
    metrics_registry::*,
    std::path::PathBuf,
};

pub use input_device_constants::InputDeviceType;

/// The path to the input-report directory.
pub static INPUT_REPORT_PATH: &str = "/dev/class/input-report";

const LATENCY_HISTOGRAM_PROPERTIES: ExponentialHistogramParams<i64> = ExponentialHistogramParams {
    floor: 0,
    initial_step: 1,
    step_multiplier: 10,
    // Seven buckets allows us to report
    // *      < 0 msec (added automatically by Inspect)
    // *      0-1 msec
    // *     1-10 msec
    // *   10-100 msec
    // * 100-1000 msec
    // *     1-10 sec
    // *   10-100 sec
    // * 100-1000 sec
    // *    >1000 sec (added automatically by Inspect)
    buckets: 7,
};

/// An [`InputDeviceStatus`] is tied to an [`InputDeviceBinding`] and provides properties
/// detailing its Inspect status.
pub struct InputDeviceStatus {
    /// Function for getting the current timestamp. Enables unit testing
    /// of the latency histogram.
    now: Box<dyn Fn() -> zx::Time>,

    /// A node that contains the state below.
    _node: fuchsia_inspect::Node,

    /// The total number of reports received by the device driver.
    reports_received_count: fuchsia_inspect::UintProperty,

    /// The number of reports received by the device driver that did
    /// not get converted into InputEvents processed by InputPipeline.
    reports_filtered_count: fuchsia_inspect::UintProperty,

    /// The total number of events generated from received
    /// InputReports that were sent to InputPipeline.
    events_generated: fuchsia_inspect::UintProperty,

    /// The event time the last received InputReport was generated.
    last_received_timestamp_ns: fuchsia_inspect::UintProperty,

    /// The event time the last InputEvent was generated.
    last_generated_timestamp_ns: fuchsia_inspect::UintProperty,

    // This node records the health status of the `InputDevice`.
    pub health_node: fuchsia_inspect::health::Node,

    /// Histogram of latency from the driver timestamp for an `InputReport` until
    /// the time at which the report was seen by the respective binding. Reported
    /// in milliseconds, because values less than 1 msec aren't especially
    /// interesting.
    driver_to_binding_latency_ms: fuchsia_inspect::IntExponentialHistogramProperty,
}

impl InputDeviceStatus {
    pub fn new(device_node: fuchsia_inspect::Node) -> Self {
        Self::new_internal(device_node, Box::new(zx::Time::get_monotonic))
    }

    fn new_internal(device_node: fuchsia_inspect::Node, now: Box<dyn Fn() -> zx::Time>) -> Self {
        let mut health_node = fuchsia_inspect::health::Node::new(&device_node);
        health_node.set_starting_up();

        let reports_received_count = device_node.create_uint("reports_received_count", 0);
        let reports_filtered_count = device_node.create_uint("reports_filtered_count", 0);
        let events_generated = device_node.create_uint("events_generated", 0);
        let last_received_timestamp_ns = device_node.create_uint("last_received_timestamp_ns", 0);
        let last_generated_timestamp_ns = device_node.create_uint("last_generated_timestamp_ns", 0);
        let driver_to_binding_latency_ms = device_node.create_int_exponential_histogram(
            "driver_to_binding_latency_ms",
            LATENCY_HISTOGRAM_PROPERTIES,
        );

        Self {
            now,
            _node: device_node,
            reports_received_count,
            reports_filtered_count,
            events_generated,
            last_received_timestamp_ns,
            last_generated_timestamp_ns,
            health_node,
            driver_to_binding_latency_ms,
        }
    }

    pub fn count_received_report(&self, report: &InputReport) {
        self.reports_received_count.add(1);
        match report.event_time {
            Some(event_time) => {
                self.driver_to_binding_latency_ms
                    .insert(((self.now)() - zx::Time::from_nanos(event_time)).into_millis());
                self.last_received_timestamp_ns.set(event_time.try_into().unwrap());
            }
            None => (),
        }
    }

    pub fn count_filtered_report(&self) {
        self.reports_filtered_count.add(1);
    }

    pub fn count_generated_event(&self, event: InputEvent) {
        self.events_generated.add(1);
        self.last_generated_timestamp_ns.set(event.event_time.into_nanos().try_into().unwrap());
    }
}

/// An [`InputEvent`] holds information about an input event and the device that produced the event.
#[derive(Clone, Debug, PartialEq)]
pub struct InputEvent {
    /// The `device_event` contains the device-specific input event information.
    pub device_event: InputDeviceEvent,

    /// The `device_descriptor` contains static information about the device that generated the
    /// input event.
    pub device_descriptor: InputDeviceDescriptor,

    /// The time in nanoseconds when the event was first recorded.
    pub event_time: zx::Time,

    /// The handled state of the event.
    pub handled: Handled,

    pub trace_id: Option<ftrace::Id>,
}

/// An [`UnhandledInputEvent`] is like an [`InputEvent`], except that the data represents an
/// event that has not been handled.
/// * Event producers must not use this type to carry data for an event that was already
///   handled.
/// * Event consumers should assume that the event has not been handled.
#[derive(Clone, Debug, PartialEq)]
pub struct UnhandledInputEvent {
    /// The `device_event` contains the device-specific input event information.
    pub device_event: InputDeviceEvent,

    /// The `device_descriptor` contains static information about the device that generated the
    /// input event.
    pub device_descriptor: InputDeviceDescriptor,

    /// The time in nanoseconds when the event was first recorded.
    pub event_time: zx::Time,

    pub trace_id: Option<ftrace::Id>,
}

/// An [`InputDeviceEvent`] represents an input event from an input device.
///
/// [`InputDeviceEvent`]s contain more context than the raw [`InputReport`] they are parsed from.
/// For example, [`KeyboardEvent`] contains all the pressed keys, as well as the key's
/// phase (pressed, released, etc.).
///
/// Each [`InputDeviceBinding`] generates the type of [`InputDeviceEvent`]s that are appropriate
/// for their device.
#[derive(Clone, Debug, PartialEq)]
pub enum InputDeviceEvent {
    Keyboard(keyboard_binding::KeyboardEvent),
    LightSensor(light_sensor_binding::LightSensorEvent),
    ConsumerControls(consumer_controls_binding::ConsumerControlsEvent),
    Mouse(mouse_binding::MouseEvent),
    TouchScreen(touch_binding::TouchScreenEvent),
    Touchpad(touch_binding::TouchpadEvent),
    #[cfg(test)]
    Fake,
}

/// An [`InputDescriptor`] describes the ranges of values a particular input device can generate.
///
/// For example, a [`InputDescriptor::Keyboard`] contains the keys available on the keyboard,
/// and a [`InputDescriptor::Touch`] contains the maximum number of touch contacts and the
/// range of x- and y-values each contact can take on.
///
/// The descriptor is sent alongside [`InputDeviceEvent`]s so clients can, for example, convert a
/// touch coordinate to a display coordinate. The descriptor is not expected to change for the
/// lifetime of a device binding.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum InputDeviceDescriptor {
    Keyboard(keyboard_binding::KeyboardDeviceDescriptor),
    LightSensor(light_sensor_binding::LightSensorDeviceDescriptor),
    ConsumerControls(consumer_controls_binding::ConsumerControlsDeviceDescriptor),
    Mouse(mouse_binding::MouseDeviceDescriptor),
    TouchScreen(touch_binding::TouchScreenDeviceDescriptor),
    Touchpad(touch_binding::TouchpadDeviceDescriptor),
    #[cfg(test)]
    Fake,
}

impl From<keyboard_binding::KeyboardDeviceDescriptor> for InputDeviceDescriptor {
    fn from(b: keyboard_binding::KeyboardDeviceDescriptor) -> Self {
        InputDeviceDescriptor::Keyboard(b)
    }
}

// Whether the event is consumed by an [`InputHandler`].
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Handled {
    // The event has been handled.
    Yes,
    // The event has not been handled.
    No,
}

/// An [`InputDeviceBinding`] represents a binding to an input device (e.g., a mouse).
///
/// [`InputDeviceBinding`]s expose information about the bound device. For example, a
/// [`MouseBinding`] exposes the ranges of possible x and y values the device can generate.
///
/// An [`InputPipeline`] manages [`InputDeviceBinding`]s and holds the receiving end of a channel
/// that an [`InputDeviceBinding`]s send [`InputEvent`]s over.
/// ```
#[async_trait]
pub trait InputDeviceBinding: Send {
    /// Returns information about the input device.
    fn get_device_descriptor(&self) -> InputDeviceDescriptor;

    /// Returns the input event stream's sender.
    fn input_event_sender(&self) -> UnboundedSender<InputEvent>;
}

/// Initializes the input report stream for the device bound to `device_proxy`.
///
/// Spawns a future which awaits input reports from the device and forwards them to
/// clients via `event_sender`.
///
/// # Parameters
/// - `device_proxy`: The device proxy which is used to get input reports.
/// - `device_descriptor`: The descriptor of the device bound to `device_proxy`.
/// - `event_sender`: The channel to send InputEvents to.
/// - `metrics_logger`: The metrics logger.
/// - `process_reports`: A function that generates InputEvent(s) from an InputReport and the
///                      InputReport that precedes it. Each type of input device defines how it
///                      processes InputReports.
///
pub fn initialize_report_stream<InputDeviceProcessReportsFn>(
    device_proxy: fidl_input_report::InputDeviceProxy,
    device_descriptor: InputDeviceDescriptor,
    mut event_sender: UnboundedSender<InputEvent>,
    inspect_status: InputDeviceStatus,
    metrics_logger: metrics::MetricsLogger,
    mut process_reports: InputDeviceProcessReportsFn,
) where
    InputDeviceProcessReportsFn: 'static
        + Send
        + FnMut(
            InputReport,
            Option<InputReport>,
            &InputDeviceDescriptor,
            &mut UnboundedSender<InputEvent>,
            &InputDeviceStatus,
            &metrics::MetricsLogger,
        ) -> (Option<InputReport>, Option<UnboundedReceiver<InputEvent>>),
{
    fasync::Task::local(async move {
        let mut previous_report: Option<InputReport> = None;
        let (report_reader, server_end) = match fidl::endpoints::create_proxy() {
            Ok(res) => res,
            Err(e) => {
                metrics_logger.log_error(
                    InputPipelineErrorMetricDimensionEvent::InputDeviceCreateInputReportProxyFailed,
                    std::format!("error creating InputReport proxy: {:?}", &e),
                );
                return; // TODO(https://fxbug.dev/42131965): signal error
            }
        };
        let result = device_proxy.get_input_reports_reader(server_end);
        if result.is_err() {
            metrics_logger.log_error(
                InputPipelineErrorMetricDimensionEvent::InputDeviceGetInputReportsReaderError,
                std::format!("error on GetInputReportsReader: {:?}", &result),
            );
            return; // TODO(https://fxbug.dev/42131965): signal error
        }
        let mut report_stream = HangingGetStream::new(
            report_reader,
            fidl_input_report::InputReportsReaderProxy::read_input_reports,
        );
        loop {
            match report_stream.next().await {
                Some(Ok(Ok(input_reports))) => {
                    fuchsia_trace::duration!(c"input", c"input-device-process-reports");
                    let mut inspect_receiver: Option<UnboundedReceiver<InputEvent>>;
                    for report in input_reports {
                        (previous_report, inspect_receiver) = process_reports(
                            report,
                            previous_report,
                            &device_descriptor,
                            &mut event_sender,
                            &inspect_status,
                            &metrics_logger,
                        );
                        // If a report generates multiple events asynchronously, we send them over a mpsc channel
                        // to inspect_receiver. We update the event count on inspect_status here since we cannot
                        // pass a reference to inspect_status to an async task in process_reports().
                        match inspect_receiver {
                            Some(mut receiver) => {
                                while let Some(event) = receiver.next().await {
                                    inspect_status.count_generated_event(event);
                                }
                            }
                            None => (),
                        };
                    }
                }
                Some(Ok(Err(_service_error))) => break,
                Some(Err(_fidl_error)) => break,
                None => break,
            }
        }
        // TODO(https://fxbug.dev/42131965): Add signaling for when this loop exits, since it means the device
        // binding is no longer functional.
        tracing::warn!("initialize_report_stream exited - device binding no longer works");
    })
    .detach();
}

/// Returns true if the device type of `input_device` matches `device_type`.
///
/// # Parameters
/// - `input_device`: The InputDevice to check the type of.
/// - `device_type`: The type of the device to compare to.
pub async fn is_device_type(
    device_descriptor: &fidl_input_report::DeviceDescriptor,
    device_type: InputDeviceType,
) -> bool {
    // Return if the device type matches the desired `device_type`.
    match device_type {
        InputDeviceType::ConsumerControls => device_descriptor.consumer_control.is_some(),
        InputDeviceType::Mouse => device_descriptor.mouse.is_some(),
        InputDeviceType::Touch => device_descriptor.touch.is_some(),
        InputDeviceType::Keyboard => device_descriptor.keyboard.is_some(),
        InputDeviceType::LightSensor => device_descriptor.sensor.is_some(),
    }
}

/// Returns a new [`InputDeviceBinding`] of the given device type.
///
/// # Parameters
/// - `device_type`: The type of the input device.
/// - `device_proxy`: The device proxy which is used to get input reports.
/// - `device_id`: The id of the connected input device.
/// - `input_event_sender`: The channel to send generated InputEvents to.
pub async fn get_device_binding(
    device_type: InputDeviceType,
    device_proxy: fidl_input_report::InputDeviceProxy,
    device_id: u32,
    input_event_sender: UnboundedSender<InputEvent>,
    device_node: fuchsia_inspect::Node,
    metrics_logger: metrics::MetricsLogger,
) -> Result<Box<dyn InputDeviceBinding>, Error> {
    match device_type {
        InputDeviceType::ConsumerControls => {
            let binding = consumer_controls_binding::ConsumerControlsBinding::new(
                device_proxy,
                device_id,
                input_event_sender,
                device_node,
                metrics_logger,
            )
            .await?;
            Ok(Box::new(binding))
        }
        InputDeviceType::Mouse => {
            let binding = mouse_binding::MouseBinding::new(
                device_proxy,
                device_id,
                input_event_sender,
                device_node,
                metrics_logger,
            )
            .await?;
            Ok(Box::new(binding))
        }
        InputDeviceType::Touch => {
            let binding = touch_binding::TouchBinding::new(
                device_proxy,
                device_id,
                input_event_sender,
                device_node,
                metrics_logger,
            )
            .await?;
            Ok(Box::new(binding))
        }
        InputDeviceType::Keyboard => {
            let binding = keyboard_binding::KeyboardBinding::new(
                device_proxy,
                device_id,
                input_event_sender,
                device_node,
                metrics_logger,
            )
            .await?;
            Ok(Box::new(binding))
        }
        InputDeviceType::LightSensor => {
            let binding = light_sensor_binding::LightSensorBinding::new(
                device_proxy,
                device_id,
                input_event_sender,
                device_node,
                metrics_logger,
            )
            .await?;
            Ok(Box::new(binding))
        }
    }
}

/// Returns a proxy to the InputDevice in `entry_path` if it exists.
///
/// # Parameters
/// - `dir_proxy`: The directory containing InputDevice connections.
/// - `entry_path`: The directory entry that contains an InputDevice.
///
/// # Errors
/// If there is an error connecting to the InputDevice in `entry_path`.
pub fn get_device_from_dir_entry_path(
    dir_proxy: &fio::DirectoryProxy,
    entry_path: &PathBuf,
) -> Result<fidl_input_report::InputDeviceProxy, Error> {
    let input_device_path = entry_path.to_str();
    if input_device_path.is_none() {
        return Err(format_err!("Failed to get entry path as a string."));
    }

    let (input_device, server) = fidl::endpoints::create_proxy::<InputDeviceMarker>()?;
    fdio::service_connect_at(
        dir_proxy.as_channel().as_ref(),
        input_device_path.unwrap(),
        server.into_channel(),
    )
    .expect("Failed to connect to InputDevice.");
    Ok(input_device)
}

/// Returns the event time if it exists, otherwise returns the current time.
///
/// # Parameters
/// - `event_time`: The event time from an InputReport.
pub fn event_time_or_now(event_time: Option<i64>) -> zx::Time {
    match event_time {
        Some(time) => zx::Time::from_nanos(time),
        None => zx::Time::get_monotonic(),
    }
}

impl std::convert::From<UnhandledInputEvent> for InputEvent {
    fn from(event: UnhandledInputEvent) -> Self {
        Self {
            device_event: event.device_event,
            device_descriptor: event.device_descriptor,
            event_time: event.event_time,
            handled: Handled::No,
            trace_id: event.trace_id,
        }
    }
}

// Fallible conversion from an InputEvent to an UnhandledInputEvent.
//
// Useful to adapt various functions in the [`testing_utilities`] module
// to work with tests for [`UnhandledInputHandler`]s.
//
// Production code however, should probably just match on the [`InputEvent`].
#[cfg(test)]
impl std::convert::TryFrom<InputEvent> for UnhandledInputEvent {
    type Error = anyhow::Error;
    fn try_from(event: InputEvent) -> Result<UnhandledInputEvent, Self::Error> {
        match event.handled {
            Handled::Yes => {
                Err(format_err!("Attempted to treat a handled InputEvent as unhandled"))
            }
            Handled::No => Ok(UnhandledInputEvent {
                device_event: event.device_event,
                device_descriptor: event.device_descriptor,
                event_time: event.event_time,
                trace_id: event.trace_id,
            }),
        }
    }
}

impl InputEvent {
    /// Marks the event as handled, if `predicate` is `true`.
    /// Otherwise, leaves the event unchanged.
    pub(crate) fn into_handled_if(self, predicate: bool) -> Self {
        if predicate {
            Self { handled: Handled::Yes, ..self }
        } else {
            self
        }
    }

    /// Marks the event as handled.
    pub(crate) fn into_handled(self) -> Self {
        Self { handled: Handled::Yes, ..self }
    }

    /// Returns the same event, with modified event time.
    pub fn into_with_event_time(self, event_time: zx::Time) -> Self {
        Self { event_time, ..self }
    }

    /// Returns the same event, with modified device descriptor.
    #[cfg(test)]
    pub fn into_with_device_descriptor(self, device_descriptor: InputDeviceDescriptor) -> Self {
        Self { device_descriptor, ..self }
    }

    /// Returns true if this event is marked as handled.
    pub fn is_handled(&self) -> bool {
        self.handled == Handled::Yes
    }

    // Returns event type as string.
    pub fn get_event_type(&self) -> &'static str {
        match self.device_event {
            InputDeviceEvent::Keyboard(_) => "keyboard_event",
            InputDeviceEvent::LightSensor(_) => "light_sensor_event",
            InputDeviceEvent::ConsumerControls(_) => "consumer_controls_event",
            InputDeviceEvent::Mouse(_) => "mouse_event",
            InputDeviceEvent::TouchScreen(_) => "touch_screen_event",
            InputDeviceEvent::Touchpad(_) => "touchpad_event",
            #[cfg(test)]
            InputDeviceEvent::Fake => "fake_event",
        }
    }

    pub fn record_inspect(&self, node: &fuchsia_inspect::Node) {
        node.record_int("event_time", self.event_time.into_nanos());
        match &self.device_event {
            InputDeviceEvent::LightSensor(e) => e.record_inspect(node),
            InputDeviceEvent::ConsumerControls(e) => e.record_inspect(node),
            InputDeviceEvent::Mouse(e) => e.record_inspect(node),
            InputDeviceEvent::TouchScreen(e) => e.record_inspect(node),
            InputDeviceEvent::Touchpad(e) => e.record_inspect(node),
            // No-op for KeyboardEvent, since we don't want to potentially record sensitive information to Inspect.
            InputDeviceEvent::Keyboard(_) => (),
            #[cfg(test)] // No-op for Fake InputDeviceEvent.
            InputDeviceEvent::Fake => (),
        }
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*, assert_matches::assert_matches, diagnostics_assertions::AnyProperty,
        fidl::endpoints::spawn_stream_handler, fuchsia_zircon as zx, pretty_assertions::assert_eq,
        std::convert::TryFrom as _, test_case::test_case,
    };

    #[test]
    fn max_event_time() {
        let event_time = event_time_or_now(Some(i64::MAX));
        assert_eq!(event_time, zx::Time::INFINITE);
    }

    #[test]
    fn min_event_time() {
        let event_time = event_time_or_now(Some(std::i64::MIN));
        assert_eq!(event_time, zx::Time::INFINITE_PAST);
    }

    #[fasync::run_singlethreaded(test)]
    async fn input_device_status_initialized_with_correct_properties() {
        let inspector = fuchsia_inspect::Inspector::default();
        let input_pipeline_node = inspector.root().create_child("input_pipeline");
        let input_devices_node = input_pipeline_node.create_child("input_devices");
        let device_node = input_devices_node.create_child("001_keyboard");
        let _input_device_status = InputDeviceStatus::new(device_node);
        diagnostics_assertions::assert_data_tree!(inspector, root: {
            input_pipeline: {
                input_devices: {
                    "001_keyboard": {
                        reports_received_count: 0u64,
                        reports_filtered_count: 0u64,
                        events_generated: 0u64,
                        last_received_timestamp_ns: 0u64,
                        last_generated_timestamp_ns: 0u64,
                        "fuchsia.inspect.Health": {
                            status: "STARTING_UP",
                            // Timestamp value is unpredictable and not relevant in this context,
                            // so we only assert that the property is present.
                            start_timestamp_nanos: AnyProperty
                        },
                        driver_to_binding_latency_ms: diagnostics_assertions::HistogramAssertion::exponential(super::LATENCY_HISTOGRAM_PROPERTIES),
                    }
                }
            }
        });
    }

    #[test_case(i64::MIN; "min value")]
    #[test_case(-1; "negative value")]
    #[test_case(0; "zero")]
    #[test_case(1; "positive value")]
    #[test_case(i64::MAX; "max value")]
    #[fuchsia::test(allow_stalls = false)]
    async fn input_device_status_updates_latency_histogram_on_count_received_report(
        latency_nsec: i64,
    ) {
        let mut expected_histogram = diagnostics_assertions::HistogramAssertion::exponential(
            super::LATENCY_HISTOGRAM_PROPERTIES,
        );
        let inspector = fuchsia_inspect::Inspector::default();
        let input_device_status = InputDeviceStatus::new_internal(
            inspector.root().clone_weak(),
            Box::new(move || zx::Time::from_nanos(latency_nsec)),
        );
        input_device_status
            .count_received_report(&InputReport { event_time: Some(0), ..InputReport::default() });
        expected_histogram.insert_values([latency_nsec / 1000 / 1000]);
        diagnostics_assertions::assert_data_tree!(inspector, root: contains {
            driver_to_binding_latency_ms: expected_histogram,
        });
    }

    // Tests that is_device_type() returns true for InputDeviceType::ConsumerControls when a
    // consumer controls device exists.
    #[fasync::run_singlethreaded(test)]
    async fn consumer_controls_input_device_exists() {
        let input_device_proxy: fidl_input_report::InputDeviceProxy =
            spawn_stream_handler(move |input_device_request| async move {
                match input_device_request {
                    fidl_input_report::InputDeviceRequest::GetDescriptor { responder } => {
                        let _ = responder.send(&fidl_input_report::DeviceDescriptor {
                            device_info: None,
                            mouse: None,
                            sensor: None,
                            touch: None,
                            keyboard: None,
                            consumer_control: Some(fidl_input_report::ConsumerControlDescriptor {
                                input: Some(fidl_input_report::ConsumerControlInputDescriptor {
                                    buttons: Some(vec![
                                        fidl_input_report::ConsumerControlButton::VolumeUp,
                                        fidl_input_report::ConsumerControlButton::VolumeDown,
                                    ]),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                            ..Default::default()
                        });
                    }
                    _ => panic!("InputDevice handler received an unexpected request"),
                }
            })
            .unwrap();

        assert!(
            is_device_type(
                &input_device_proxy
                    .get_descriptor()
                    .await
                    .expect("Failed to get device descriptor"),
                InputDeviceType::ConsumerControls
            )
            .await
        );
    }

    // Tests that is_device_type() returns true for InputDeviceType::Mouse when a mouse exists.
    #[fasync::run_singlethreaded(test)]
    async fn mouse_input_device_exists() {
        let input_device_proxy: fidl_input_report::InputDeviceProxy =
            spawn_stream_handler(move |input_device_request| async move {
                match input_device_request {
                    fidl_input_report::InputDeviceRequest::GetDescriptor { responder } => {
                        let _ = responder.send(&fidl_input_report::DeviceDescriptor {
                            device_info: None,
                            mouse: Some(fidl_input_report::MouseDescriptor {
                                input: Some(fidl_input_report::MouseInputDescriptor {
                                    movement_x: None,
                                    movement_y: None,
                                    position_x: None,
                                    position_y: None,
                                    scroll_v: None,
                                    scroll_h: None,
                                    buttons: None,
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                            sensor: None,
                            touch: None,
                            keyboard: None,
                            consumer_control: None,
                            ..Default::default()
                        });
                    }
                    _ => panic!("InputDevice handler received an unexpected request"),
                }
            })
            .unwrap();

        assert!(
            is_device_type(
                &input_device_proxy
                    .get_descriptor()
                    .await
                    .expect("Failed to get device descriptor"),
                InputDeviceType::Mouse
            )
            .await
        );
    }

    // Tests that is_device_type() returns true for InputDeviceType::Mouse when a mouse doesn't
    // exist.
    #[fasync::run_singlethreaded(test)]
    async fn mouse_input_device_doesnt_exist() {
        let input_device_proxy: fidl_input_report::InputDeviceProxy =
            spawn_stream_handler(move |input_device_request| async move {
                match input_device_request {
                    fidl_input_report::InputDeviceRequest::GetDescriptor { responder } => {
                        let _ = responder.send(&fidl_input_report::DeviceDescriptor {
                            device_info: None,
                            mouse: None,
                            sensor: None,
                            touch: None,
                            keyboard: None,
                            consumer_control: None,
                            ..Default::default()
                        });
                    }
                    _ => panic!("InputDevice handler received an unexpected request"),
                }
            })
            .unwrap();

        assert!(
            !is_device_type(
                &input_device_proxy
                    .get_descriptor()
                    .await
                    .expect("Failed to get device descriptor"),
                InputDeviceType::Mouse
            )
            .await
        );
    }

    // Tests that is_device_type() returns true for InputDeviceType::Touch when a touchscreen
    // exists.
    #[fasync::run_singlethreaded(test)]
    async fn touch_input_device_exists() {
        let input_device_proxy: fidl_input_report::InputDeviceProxy =
            spawn_stream_handler(move |input_device_request| async move {
                match input_device_request {
                    fidl_input_report::InputDeviceRequest::GetDescriptor { responder } => {
                        let _ = responder.send(&fidl_input_report::DeviceDescriptor {
                            device_info: None,
                            mouse: None,
                            sensor: None,
                            touch: Some(fidl_input_report::TouchDescriptor {
                                input: Some(fidl_input_report::TouchInputDescriptor {
                                    contacts: None,
                                    max_contacts: None,
                                    touch_type: None,
                                    buttons: None,
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                            keyboard: None,
                            consumer_control: None,
                            ..Default::default()
                        });
                    }
                    _ => panic!("InputDevice handler received an unexpected request"),
                }
            })
            .unwrap();

        assert!(
            is_device_type(
                &input_device_proxy
                    .get_descriptor()
                    .await
                    .expect("Failed to get device descriptor"),
                InputDeviceType::Touch
            )
            .await
        );
    }

    // Tests that is_device_type() returns true for InputDeviceType::Touch when a touchscreen
    // exists.
    #[fasync::run_singlethreaded(test)]
    async fn touch_input_device_doesnt_exist() {
        let input_device_proxy: fidl_input_report::InputDeviceProxy =
            spawn_stream_handler(move |input_device_request| async move {
                match input_device_request {
                    fidl_input_report::InputDeviceRequest::GetDescriptor { responder } => {
                        let _ = responder.send(&fidl_input_report::DeviceDescriptor {
                            device_info: None,
                            mouse: None,
                            sensor: None,
                            touch: None,
                            keyboard: None,
                            consumer_control: None,
                            ..Default::default()
                        });
                    }
                    _ => panic!("InputDevice handler received an unexpected request"),
                }
            })
            .unwrap();

        assert!(
            !is_device_type(
                &input_device_proxy
                    .get_descriptor()
                    .await
                    .expect("Failed to get device descriptor"),
                InputDeviceType::Touch
            )
            .await
        );
    }

    // Tests that is_device_type() returns true for InputDeviceType::Keyboard when a keyboard
    // exists.
    #[fasync::run_singlethreaded(test)]
    async fn keyboard_input_device_exists() {
        let input_device_proxy: fidl_input_report::InputDeviceProxy =
            spawn_stream_handler(move |input_device_request| async move {
                match input_device_request {
                    fidl_input_report::InputDeviceRequest::GetDescriptor { responder } => {
                        let _ = responder.send(&fidl_input_report::DeviceDescriptor {
                            device_info: None,
                            mouse: None,
                            sensor: None,
                            touch: None,
                            keyboard: Some(fidl_input_report::KeyboardDescriptor {
                                input: Some(fidl_input_report::KeyboardInputDescriptor {
                                    keys3: None,
                                    ..Default::default()
                                }),
                                output: None,
                                ..Default::default()
                            }),
                            consumer_control: None,
                            ..Default::default()
                        });
                    }
                    _ => panic!("InputDevice handler received an unexpected request"),
                }
            })
            .unwrap();

        assert!(
            is_device_type(
                &input_device_proxy
                    .get_descriptor()
                    .await
                    .expect("Failed to get device descriptor"),
                InputDeviceType::Keyboard
            )
            .await
        );
    }

    // Tests that is_device_type() returns true for InputDeviceType::Keyboard when a keyboard
    // exists.
    #[fasync::run_singlethreaded(test)]
    async fn keyboard_input_device_doesnt_exist() {
        let input_device_proxy: fidl_input_report::InputDeviceProxy =
            spawn_stream_handler(move |input_device_request| async move {
                match input_device_request {
                    fidl_input_report::InputDeviceRequest::GetDescriptor { responder } => {
                        let _ = responder.send(&fidl_input_report::DeviceDescriptor {
                            device_info: None,
                            mouse: None,
                            sensor: None,
                            touch: None,
                            keyboard: None,
                            consumer_control: None,
                            ..Default::default()
                        });
                    }
                    _ => panic!("InputDevice handler received an unexpected request"),
                }
            })
            .unwrap();

        assert!(
            !is_device_type(
                &input_device_proxy
                    .get_descriptor()
                    .await
                    .expect("Failed to get device descriptor"),
                InputDeviceType::Keyboard
            )
            .await
        );
    }

    // Tests that is_device_type() returns true for every input device type that exists.
    #[fasync::run_singlethreaded(test)]
    async fn no_input_device_match() {
        let input_device_proxy: fidl_input_report::InputDeviceProxy =
            spawn_stream_handler(move |input_device_request| async move {
                match input_device_request {
                    fidl_input_report::InputDeviceRequest::GetDescriptor { responder } => {
                        let _ = responder.send(&fidl_input_report::DeviceDescriptor {
                            device_info: None,
                            mouse: Some(fidl_input_report::MouseDescriptor {
                                input: Some(fidl_input_report::MouseInputDescriptor {
                                    movement_x: None,
                                    movement_y: None,
                                    position_x: None,
                                    position_y: None,
                                    scroll_v: None,
                                    scroll_h: None,
                                    buttons: None,
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                            sensor: None,
                            touch: Some(fidl_input_report::TouchDescriptor {
                                input: Some(fidl_input_report::TouchInputDescriptor {
                                    contacts: None,
                                    max_contacts: None,
                                    touch_type: None,
                                    buttons: None,
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                            keyboard: Some(fidl_input_report::KeyboardDescriptor {
                                input: Some(fidl_input_report::KeyboardInputDescriptor {
                                    keys3: None,
                                    ..Default::default()
                                }),
                                output: None,
                                ..Default::default()
                            }),
                            consumer_control: Some(fidl_input_report::ConsumerControlDescriptor {
                                input: Some(fidl_input_report::ConsumerControlInputDescriptor {
                                    buttons: Some(vec![
                                        fidl_input_report::ConsumerControlButton::VolumeUp,
                                        fidl_input_report::ConsumerControlButton::VolumeDown,
                                    ]),
                                    ..Default::default()
                                }),
                                ..Default::default()
                            }),
                            ..Default::default()
                        });
                    }
                    _ => panic!("InputDevice handler received an unexpected request"),
                }
            })
            .unwrap();

        let device_descriptor =
            &input_device_proxy.get_descriptor().await.expect("Failed to get device descriptor");
        assert!(is_device_type(&device_descriptor, InputDeviceType::ConsumerControls).await);
        assert!(is_device_type(&device_descriptor, InputDeviceType::Mouse).await);
        assert!(is_device_type(&device_descriptor, InputDeviceType::Touch).await);
        assert!(is_device_type(&device_descriptor, InputDeviceType::Keyboard).await);
    }

    #[fuchsia::test]
    fn unhandled_to_generic_conversion_sets_handled_flag_to_no() {
        assert_eq!(
            InputEvent::from(UnhandledInputEvent {
                device_event: InputDeviceEvent::Fake,
                device_descriptor: InputDeviceDescriptor::Fake,
                event_time: zx::Time::from_nanos(1),
                trace_id: None,
            })
            .handled,
            Handled::No
        );
    }

    #[fuchsia::test]
    fn unhandled_to_generic_conversion_preserves_fields() {
        const EVENT_TIME: zx::Time = zx::Time::from_nanos(42);
        let expected_trace_id: Option<ftrace::Id> = Some(1234.into());
        assert_matches!(
            InputEvent::from(UnhandledInputEvent {
                device_event: InputDeviceEvent::Fake,
                device_descriptor: InputDeviceDescriptor::Fake,
                event_time: EVENT_TIME,
                trace_id: expected_trace_id,
            }),
            InputEvent {
                device_event: InputDeviceEvent::Fake,
                device_descriptor: InputDeviceDescriptor::Fake,
                event_time: EVENT_TIME,
                handled: _,
                trace_id
            } if trace_id == expected_trace_id
        );
    }

    #[fuchsia::test]
    fn generic_to_unhandled_conversion_fails_for_handled_events() {
        assert_matches!(
            UnhandledInputEvent::try_from(InputEvent {
                device_event: InputDeviceEvent::Fake,
                device_descriptor: InputDeviceDescriptor::Fake,
                event_time: zx::Time::from_nanos(1),
                handled: Handled::Yes,
                trace_id: None,
            }),
            Err(_)
        )
    }

    #[fuchsia::test]
    fn generic_to_unhandled_conversion_preserves_fields_for_unhandled_events() {
        const EVENT_TIME: zx::Time = zx::Time::from_nanos(42);
        let expected_trace_id: Option<ftrace::Id> = Some(1234.into());
        assert_matches!(
            UnhandledInputEvent::try_from(InputEvent {
                device_event: InputDeviceEvent::Fake,
                device_descriptor: InputDeviceDescriptor::Fake,
                event_time: EVENT_TIME,
                handled: Handled::No,
                trace_id: expected_trace_id,
            }),
            Ok(UnhandledInputEvent {
                device_event: InputDeviceEvent::Fake,
                device_descriptor: InputDeviceDescriptor::Fake,
                event_time: EVENT_TIME,
                trace_id
            }) if trace_id == expected_trace_id
        )
    }

    #[test_case(Handled::No; "initially not handled")]
    #[test_case(Handled::Yes; "initially handled")]
    fn into_handled_if_yields_handled_yes_on_true(initially_handled: Handled) {
        let event = InputEvent {
            device_event: InputDeviceEvent::Fake,
            device_descriptor: InputDeviceDescriptor::Fake,
            event_time: zx::Time::from_nanos(1),
            handled: initially_handled,
            trace_id: None,
        };
        pretty_assertions::assert_eq!(event.into_handled_if(true).handled, Handled::Yes);
    }

    #[test_case(Handled::No; "initially not handled")]
    #[test_case(Handled::Yes; "initially handled")]
    fn into_handled_if_leaves_handled_unchanged_on_false(initially_handled: Handled) {
        let event = InputEvent {
            device_event: InputDeviceEvent::Fake,
            device_descriptor: InputDeviceDescriptor::Fake,
            event_time: zx::Time::from_nanos(1),
            handled: initially_handled.clone(),
            trace_id: None,
        };
        pretty_assertions::assert_eq!(event.into_handled_if(false).handled, initially_handled);
    }

    #[test_case(Handled::No; "initially not handled")]
    #[test_case(Handled::Yes; "initially handled")]
    fn into_handled_yields_handled_yes(initially_handled: Handled) {
        let event = InputEvent {
            device_event: InputDeviceEvent::Fake,
            device_descriptor: InputDeviceDescriptor::Fake,
            event_time: zx::Time::from_nanos(1),
            handled: initially_handled,
            trace_id: None,
        };
        pretty_assertions::assert_eq!(event.into_handled().handled, Handled::Yes);
    }
}
