// 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::input_device::{self, Handled, InputDeviceBinding},
    crate::utils::Position,
    anyhow::{format_err, Error},
    async_trait::async_trait,
    fidl_fuchsia_input_report as fidl_input_report,
    fidl_fuchsia_input_report::{InputDeviceProxy, InputReport},
    fuchsia_syslog::fx_log_err,
    fuchsia_zircon as zx,
    futures::channel::mpsc::Sender,
    std::collections::HashSet,
    std::iter::FromIterator,
};

pub type MouseButton = u8;

/// A [`MouseLocation`] represents the mouse pointer location at the time of a pointer event.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum MouseLocation {
    /// A mouse movement relative to its current position.
    Relative(RelativeLocation),

    /// An absolute position, in device coordinates.
    Absolute(Position),
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum MousePhase {
    Down,  // One or more buttons were newly pressed.
    Move,  // The mouse moved with no change in button state.
    Up,    // One or more buttons were newly released.
    Wheel, // Mouse wheel is rotating.
}

/// A [`RelativeLocation`] contains the relative mouse pointer location at the time of a pointer event.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct RelativeLocation {
    /// A pointer location in device-specific counts.
    pub counts: Position,
    /// A pointer location in millimeters.
    pub millimeters: Position,
}

impl Default for RelativeLocation {
    fn default() -> Self {
        RelativeLocation { counts: Position::zero(), millimeters: Position::zero() }
    }
}

/// A [`MouseEvent`] represents a pointer event with a specified phase, and the buttons
/// involved in said phase. The supported phases for mice include Up, Down, and Move.
///
/// # Example
/// The following MouseEvent represents a relative movement of 40 units in the x axis
/// and 20 units in the y axis while holding the primary button (1) down.
///
/// ```
/// let mouse_device_event = input_device::InputDeviceEvent::Mouse(MouseEvent::new(
///     MouseLocation::Relative(RelativePosition {
///       counts: Position { x: 40.0, y: 20.0 },
///       millimeters: Position { x: _, y: _ },
///     }),
///     Some(1),
///     Some(1),
///     MousePhase::Move,
///     HashSet::from_iter(vec![1]).into_iter()),
///     HashSet::from_iter(vec![1]).into_iter()),,
/// ));
/// ```
#[derive(Clone, Debug, PartialEq)]
pub struct MouseEvent {
    /// The mouse location.
    pub location: MouseLocation,

    /// The mouse wheel rotated delta in vertical.
    pub wheel_delta_v: Option<i64>,

    /// The mouse wheel rotated delta in horizontal.
    pub wheel_delta_h: Option<i64>,

    /// The phase of the [`buttons`] associated with this input event.
    pub phase: MousePhase,

    /// The buttons relevant to this event.
    pub affected_buttons: HashSet<MouseButton>,

    /// The complete button state including this event.
    pub pressed_buttons: HashSet<MouseButton>,
}

impl MouseEvent {
    /// Creates a new [`MouseEvent`].
    ///
    /// # Parameters
    /// - `location`: The mouse location.
    /// - `phase`: The phase of the [`buttons`] associated with this input event.
    /// - `buttons`: The buttons relevant to this event.
    pub fn new(
        location: MouseLocation,
        wheel_delta_v: Option<i64>,
        wheel_delta_h: Option<i64>,
        phase: MousePhase,
        affected_buttons: HashSet<MouseButton>,
        pressed_buttons: HashSet<MouseButton>,
    ) -> MouseEvent {
        MouseEvent {
            location,
            wheel_delta_v,
            wheel_delta_h,
            phase,
            affected_buttons,
            pressed_buttons,
        }
    }
}

/// A [`MouseBinding`] represents a connection to a mouse input device.
///
/// The [`MouseBinding`] parses and exposes mouse descriptor properties (e.g., the range of
/// possible x values) for the device it is associated with. It also parses [`InputReport`]s
/// from the device, and sends them to the device binding owner over `event_sender`.
pub struct MouseBinding {
    /// The channel to stream InputEvents to.
    event_sender: Sender<input_device::InputEvent>,

    /// Holds information about this device.
    device_descriptor: MouseDeviceDescriptor,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct MouseDeviceDescriptor {
    /// The id of the connected mouse input device.
    pub device_id: u32,

    /// The range of possible x values of absolute mouse positions reported by this device.
    pub absolute_x_range: Option<fidl_input_report::Range>,

    /// The range of possible y values of absolute mouse positions reported by this device.
    pub absolute_y_range: Option<fidl_input_report::Range>,

    /// The range of possible vertical wheel delta reported by this device.
    pub wheel_v_range: Option<fidl_input_report::Axis>,

    /// The range of possible horizontal wheel delta reported by this device.
    pub wheel_h_range: Option<fidl_input_report::Axis>,

    /// This is a vector of ids for the mouse buttons.
    pub buttons: Option<Vec<MouseButton>>,
}

#[async_trait]
impl input_device::InputDeviceBinding for MouseBinding {
    fn input_event_sender(&self) -> Sender<input_device::InputEvent> {
        self.event_sender.clone()
    }

    fn get_device_descriptor(&self) -> input_device::InputDeviceDescriptor {
        input_device::InputDeviceDescriptor::Mouse(self.device_descriptor.clone())
    }
}

impl MouseBinding {
    /// Creates a new [`InputDeviceBinding`] from the `device_proxy`.
    ///
    /// The binding will start listening for input reports immediately and send new InputEvents
    /// to the device binding owner over `input_event_sender`.
    ///
    /// # Parameters
    /// - `device_proxy`: The proxy to bind the new [`InputDeviceBinding`] to.
    /// - `device_id`: The id of the connected mouse device.
    /// - `input_event_sender`: The channel to send new InputEvents to.
    ///
    /// # Errors
    /// If there was an error binding to the proxy.
    pub async fn new(
        device_proxy: InputDeviceProxy,
        device_id: u32,
        input_event_sender: Sender<input_device::InputEvent>,
    ) -> Result<Self, Error> {
        let device_binding =
            Self::bind_device(&device_proxy, device_id, input_event_sender).await?;
        input_device::initialize_report_stream(
            device_proxy,
            device_binding.get_device_descriptor(),
            device_binding.input_event_sender(),
            Self::process_reports,
        );

        Ok(device_binding)
    }

    /// Binds the provided input device to a new instance of `Self`.
    ///
    /// # Parameters
    /// - `device`: The device to use to initialize the binding.
    /// - `device_id`: The id of the connected mouse device.
    /// - `input_event_sender`: The channel to send new InputEvents to.
    ///
    /// # Errors
    /// If the device descriptor could not be retrieved, or the descriptor could
    /// not be parsed correctly.
    async fn bind_device(
        device: &InputDeviceProxy,
        device_id: u32,
        input_event_sender: Sender<input_device::InputEvent>,
    ) -> Result<Self, Error> {
        let device_descriptor: fidl_input_report::DeviceDescriptor =
            device.get_descriptor().await?;

        let mouse_descriptor = device_descriptor
            .mouse
            .ok_or_else(|| format_err!("DeviceDescriptor does not have a MouseDescriptor"))?;

        let mouse_input_descriptor = mouse_descriptor
            .input
            .ok_or_else(|| format_err!("MouseDescriptor does not have a MouseInputDescriptor"))?;

        let device_descriptor: MouseDeviceDescriptor = MouseDeviceDescriptor {
            device_id,
            absolute_x_range: mouse_input_descriptor.position_x.map(|axis| axis.range),
            absolute_y_range: mouse_input_descriptor.position_y.map(|axis| axis.range),
            wheel_v_range: mouse_input_descriptor.scroll_v,
            wheel_h_range: mouse_input_descriptor.scroll_h,
            buttons: mouse_input_descriptor.buttons,
        };

        Ok(MouseBinding { event_sender: input_event_sender, device_descriptor })
    }

    /// Parses an [`InputReport`] into one or more [`InputEvent`]s.
    ///
    /// The [`InputEvent`]s are sent to the device binding owner via [`input_event_sender`].
    ///
    /// # Parameters
    /// `report`: The incoming [`InputReport`].
    /// `previous_report`: The previous [`InputReport`] seen for the same device. This can be
    ///                    used to determine, for example, which keys are no longer present in
    ///                    a keyboard report to generate key released events. If `None`, no
    ///                    previous report was found.
    /// `device_descriptor`: The descriptor for the input device generating the input reports.
    /// `input_event_sender`: The sender for the device binding's input event stream.
    ///
    /// # Returns
    /// An [`InputReport`] which will be passed to the next call to [`process_reports`], as
    /// [`previous_report`]. If `None`, the next call's [`previous_report`] will be `None`.
    fn process_reports(
        report: InputReport,
        previous_report: Option<InputReport>,
        device_descriptor: &input_device::InputDeviceDescriptor,
        input_event_sender: &mut Sender<input_device::InputEvent>,
    ) -> Option<InputReport> {
        // Input devices can have multiple types so ensure `report` is a MouseInputReport.
        let mouse_report: &fidl_input_report::MouseInputReport = match &report.mouse {
            Some(mouse) => mouse,
            None => {
                return previous_report;
            }
        };

        let previous_buttons: HashSet<MouseButton> =
            buttons_from_optional_report(&previous_report.as_ref());
        let current_buttons: HashSet<MouseButton> = buttons_from_report(&report);

        let event_time: zx::Time = input_device::event_time_or_now(report.event_time);

        // Send a Down event with:
        // * affected_buttons: the buttons that were pressed since the previous report,
        //   i.e. that are in the current report, but were not in the previous report.
        // * pressed_buttons: the full set of currently pressed buttons, including the
        //   recently pressed ones (affected_buttons).
        send_mouse_event(
            MouseLocation::Relative(Default::default()),
            None, /* wheel_delta_v */
            None, /* wheel_delta_h */
            MousePhase::Down,
            current_buttons.difference(&previous_buttons).cloned().collect(),
            current_buttons.clone(),
            device_descriptor,
            event_time,
            input_event_sender,
        );

        // Create a location for the move event. Use the absolute position if available.
        let location = if let (Some(position_x), Some(position_y)) =
            (mouse_report.position_x, mouse_report.position_y)
        {
            MouseLocation::Absolute(Position { x: position_x as f32, y: position_y as f32 })
        } else {
            MouseLocation::Relative(RelativeLocation {
                counts: Position {
                    x: mouse_report.movement_x.unwrap_or_default() as f32,
                    y: mouse_report.movement_y.unwrap_or_default() as f32,
                },
                // TODO(https://fxbug.dev/102566): Implement millimeters.
                millimeters: Position::zero(),
            })
        };

        // Send a Move event with buttons from both the current report and the previous report.
        // * affected_buttons and pressed_buttons are identical in this case, since the full
        //   set of currently pressed buttons are the same set affected by the event.
        send_mouse_event(
            location,
            None, /* wheel_delta_v */
            None, /* wheel_delta_h */
            MousePhase::Move,
            current_buttons.union(&previous_buttons).cloned().collect(),
            current_buttons.union(&previous_buttons).cloned().collect(),
            device_descriptor,
            event_time,
            input_event_sender,
        );

        // Send a mouse wheel event.
        send_mouse_event(
            MouseLocation::Relative(Default::default()),
            mouse_report.scroll_v,
            mouse_report.scroll_h,
            MousePhase::Wheel,
            current_buttons.union(&previous_buttons).cloned().collect(),
            current_buttons.union(&previous_buttons).cloned().collect(),
            device_descriptor,
            event_time,
            input_event_sender,
        );

        // Send an Up event with:
        // * affected_buttons: the buttons that were released since the previous report,
        //   i.e. that were in the previous report, but are not in the current report.
        // * pressed_buttons: the full set of currently pressed buttons, excluding the
        //   recently released ones (affected_buttons).
        send_mouse_event(
            MouseLocation::Relative(Default::default()),
            None, /* wheel_delta_v */
            None, /* wheel_delta_h */
            MousePhase::Up,
            previous_buttons.difference(&current_buttons).cloned().collect(),
            current_buttons.clone(),
            device_descriptor,
            event_time,
            input_event_sender,
        );

        Some(report)
    }
}

/// Sends an InputEvent over `sender`.
///
/// When no buttons are present, only [`MousePhase::Move`] events will
/// be sent.
///
/// # Parameters
/// - `location`: The mouse location.
/// - `wheel_delta_v`: The mouse wheel delta in vertical.
/// - `wheel_delta_h`: The mouse wheel delta in horizontal.
/// - `phase`: The phase of the [`buttons`] associated with the input event.
/// - `buttons`: The buttons relevant to the event.
/// - `device_descriptor`: The descriptor for the input device generating the input reports.
/// - `event_time`: The time in nanoseconds when the event was first recorded.
/// - `sender`: The stream to send the MouseEvent to.
fn send_mouse_event(
    location: MouseLocation,
    wheel_delta_v: Option<i64>,
    wheel_delta_h: Option<i64>,
    phase: MousePhase,
    affected_buttons: HashSet<MouseButton>,
    pressed_buttons: HashSet<MouseButton>,
    device_descriptor: &input_device::InputDeviceDescriptor,
    event_time: zx::Time,
    sender: &mut Sender<input_device::InputEvent>,
) {
    // Only send Down/Up events when there are buttons affected.
    if (phase == MousePhase::Down || phase == MousePhase::Up) && affected_buttons.is_empty() {
        return;
    }

    // Don't send Move events when there is no relative movement.
    // However, absolute movement is always reported.
    if phase == MousePhase::Move && location == MouseLocation::Relative(Default::default()) {
        return;
    }

    // Only send wheel events when the delta has value.
    if phase == MousePhase::Wheel && wheel_delta_v.is_none() && wheel_delta_h.is_none() {
        return;
    }

    match sender.try_send(input_device::InputEvent {
        device_event: input_device::InputDeviceEvent::Mouse(MouseEvent::new(
            location,
            wheel_delta_v,
            wheel_delta_h,
            phase,
            affected_buttons,
            pressed_buttons,
        )),
        device_descriptor: device_descriptor.clone(),
        event_time,
        handled: Handled::No,
        trace_id: None,
    }) {
        Err(e) => fx_log_err!("Failed to send MouseEvent with error: {:?}", e),
        _ => {}
    }
}

/// Returns a u32 representation of `buttons`, where each u8 of `buttons` is an id of a button and
/// indicates the position of a bit to set.
///
/// This supports hashsets with numbers from 1 to fidl_input_report::MOUSE_MAX_NUM_BUTTONS.
///
/// # Parameters
/// - `buttons`: The hashset containing the position of bits to be set.
///
/// # Example
/// ```
/// let bits = get_u32_from_buttons(&HashSet::from_iter(vec![1, 3, 5]).into_iter());
/// assert_eq!(bits, 21 /* ...00010101 */)
/// ```
pub fn get_u32_from_buttons(buttons: &HashSet<MouseButton>) -> u32 {
    let mut bits: u32 = 0;
    for button in buttons {
        if *button > 0 && *button <= fidl_input_report::MOUSE_MAX_NUM_BUTTONS as u8 {
            bits = ((1 as u32) << *button - 1) | bits;
        }
    }

    bits
}

/// Returns the set of pressed buttons present in the given input report.
///
/// # Parameters
/// - `report`: The input report to parse the mouse buttons from.
fn buttons_from_report(input_report: &fidl_input_report::InputReport) -> HashSet<MouseButton> {
    buttons_from_optional_report(&Some(input_report))
}

/// Returns the set of pressed buttons present in the given input report.
///
/// # Parameters
/// - `report`: The input report to parse the mouse buttons from.
fn buttons_from_optional_report(
    input_report: &Option<&fidl_input_report::InputReport>,
) -> HashSet<MouseButton> {
    input_report
        .as_ref()
        .and_then(|unwrapped_report| unwrapped_report.mouse.as_ref())
        .and_then(|mouse_report| match &mouse_report.pressed_buttons {
            Some(buttons) => Some(HashSet::from_iter(buttons.iter().cloned())),
            None => None,
        })
        .unwrap_or_default()
}

#[cfg(test)]
mod tests {
    use {
        super::*, crate::testing_utilities, fidl_fuchsia_input_report, fuchsia_async as fasync,
        futures::StreamExt, pretty_assertions::assert_eq,
    };

    const DEVICE_ID: u32 = 1;

    fn mouse_device_descriptor(device_id: u32) -> input_device::InputDeviceDescriptor {
        input_device::InputDeviceDescriptor::Mouse(MouseDeviceDescriptor {
            device_id,
            absolute_x_range: None,
            absolute_y_range: None,
            wheel_v_range: Some(fidl_fuchsia_input_report::Axis {
                range: fidl_input_report::Range { min: -1, max: 1 },
                unit: fidl_input_report::Unit {
                    type_: fidl_input_report::UnitType::Other,
                    exponent: 1,
                },
            }),
            wheel_h_range: Some(fidl_fuchsia_input_report::Axis {
                range: fidl_input_report::Range { min: -1, max: 1 },
                unit: fidl_input_report::Unit {
                    type_: fidl_input_report::UnitType::Other,
                    exponent: 1,
                },
            }),
            buttons: None,
        })
    }

    // Tests that the right u32 representation is returned from a vector of digits.
    #[test]
    fn get_u32_from_buttons_test() {
        let bits = get_u32_from_buttons(&HashSet::from_iter(vec![1, 3, 5].into_iter()));
        assert_eq!(bits, 21 /* 0...00010101 */)
    }

    // Tests that the right u32 representation is returned from a vector of digits that includes 0.
    #[test]
    fn get_u32_with_0_in_vector() {
        let bits = get_u32_from_buttons(&HashSet::from_iter(vec![0, 1, 3].into_iter()));
        assert_eq!(bits, 5 /* 0...00000101 */)
    }

    // Tests that the right u32 representation is returned from an empty vector.
    #[test]
    fn get_u32_with_empty_vector() {
        let bits = get_u32_from_buttons(&HashSet::new());
        assert_eq!(bits, 0 /* 0...00000000 */)
    }

    // Tests that the right u32 representation is returned from a vector containing std::u8::MAX.
    #[test]
    fn get_u32_with_u8_max_in_vector() {
        let bits = get_u32_from_buttons(&HashSet::from_iter(vec![1, 3, std::u8::MAX].into_iter()));
        assert_eq!(bits, 5 /* 0...00000101 */)
    }

    // Tests that the right u32 representation is returned from a vector containing the largest
    // button id possible.
    #[test]
    fn get_u32_with_max_mouse_buttons() {
        let bits = get_u32_from_buttons(&HashSet::from_iter(
            vec![1, 3, fidl_input_report::MOUSE_MAX_NUM_BUTTONS as MouseButton].into_iter(),
        ));
        assert_eq!(bits, 2147483653 /* 10...00000101 */)
    }

    /// Tests that a report containing no buttons but with movement generates a move event.
    #[fasync::run_singlethreaded(test)]
    async fn movement_without_button() {
        let location = MouseLocation::Relative(RelativeLocation {
            counts: Position { x: 10.0, y: 16.0 },
            millimeters: Position::zero(),
        });
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            location,
            None, /* scroll_v */
            None, /* scroll_h */
            vec![],
            event_time_i64,
        );
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report];
        let expected_events = vec![testing_utilities::create_mouse_event(
            location,
            None, /* wheel_delta_v */
            None, /* wheel_delta_h */
            MousePhase::Move,
            HashSet::new(),
            HashSet::new(),
            event_time_u64,
            &descriptor,
        )];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that a report containing a new mouse button generates a down event.
    #[fasync::run_singlethreaded(test)]
    async fn down_without_movement() {
        let mouse_button: MouseButton = 3;
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![mouse_button],
            event_time_i64,
        );
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report];
        let expected_events = vec![testing_utilities::create_mouse_event(
            MouseLocation::Relative(Default::default()),
            None, /* wheel_delta_v */
            None, /* wheel_delta_h */
            MousePhase::Down,
            HashSet::from_iter(vec![mouse_button].into_iter()),
            HashSet::from_iter(vec![mouse_button].into_iter()),
            event_time_u64,
            &descriptor,
        )];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that a report containing a new mouse button with movement generates a down event and a
    /// move event.
    #[fasync::run_singlethreaded(test)]
    async fn down_with_movement() {
        let location = MouseLocation::Relative(RelativeLocation {
            counts: Position { x: 10.0, y: 16.0 },
            millimeters: Position::zero(),
        });
        let mouse_button: MouseButton = 3;
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            location,
            None, /* scroll_v */
            None, /* scroll_h */
            vec![mouse_button],
            event_time_i64,
        );
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![mouse_button].into_iter()),
                HashSet::from_iter(vec![mouse_button].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                location,
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Move,
                HashSet::from_iter(vec![mouse_button].into_iter()),
                HashSet::from_iter(vec![mouse_button].into_iter()),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that a press and release of a mouse button without movement generates a down and up event.
    #[fasync::run_singlethreaded(test)]
    async fn down_up() {
        let button = 1;
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![button],
            event_time_i64,
        );
        let second_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![],
            event_time_i64,
        );
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report, second_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![button].into_iter()),
                HashSet::from_iter(vec![button].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Up,
                HashSet::from_iter(vec![button].into_iter()),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that a press and release of a mouse button with movement generates down, move, and up events.
    #[fasync::run_singlethreaded(test)]
    async fn down_up_with_movement() {
        let location = MouseLocation::Relative(RelativeLocation {
            counts: Position { x: 10.0, y: 16.0 },
            millimeters: Position::zero(),
        });
        let button = 1;

        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![button],
            event_time_i64,
        );
        let second_report = testing_utilities::create_mouse_input_report(
            location,
            None, /* scroll_v */
            None, /* scroll_h */
            vec![],
            event_time_i64,
        );
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report, second_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![button].into_iter()),
                HashSet::from_iter(vec![button].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                location,
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Move,
                HashSet::from_iter(vec![button].into_iter()),
                HashSet::from_iter(vec![button].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Up,
                HashSet::from_iter(vec![button].into_iter()),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that a press, move, and release of a button generates down, move, and up events.
    /// This specifically tests the separate input report containing the movement, instead of sending
    /// the movement as part of the down or up events.
    #[fasync::run_singlethreaded(test)]
    async fn down_move_up() {
        let location = MouseLocation::Relative(RelativeLocation {
            counts: Position { x: 10.0, y: 16.0 },
            millimeters: Position::zero(),
        });
        let button = 1;

        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![button],
            event_time_i64,
        );
        let second_report = testing_utilities::create_mouse_input_report(
            location,
            None, /* scroll_v */
            None, /* scroll_h */
            vec![button],
            event_time_i64,
        );
        let third_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![],
            event_time_i64,
        );
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report, second_report, third_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![button].into_iter()),
                HashSet::from_iter(vec![button].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                location,
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Move,
                HashSet::from_iter(vec![button].into_iter()),
                HashSet::from_iter(vec![button].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Up,
                HashSet::from_iter(vec![button].into_iter()),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that a report with absolute movement to {0, 0} generates a move event.
    #[fasync::run_until_stalled(test)]
    async fn absolute_movement_to_origin() {
        let location = MouseLocation::Absolute(Position { x: 0.0, y: 0.0 });
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![testing_utilities::create_mouse_input_report(
            location,
            None, /* wheel_delta_v */
            None, /* wheel_delta_h */
            vec![],
            event_time_i64,
        )];
        let expected_events = vec![testing_utilities::create_mouse_event(
            location,
            None, /* wheel_delta_v */
            None, /* wheel_delta_h */
            MousePhase::Move,
            HashSet::new(),
            HashSet::new(),
            event_time_u64,
            &descriptor,
        )];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that a report that contains both a relative movement and absolute position
    /// generates a move event to the absolute position.
    #[fasync::run_until_stalled(test)]
    async fn report_with_both_movement_and_position() {
        let relative_movement = Position { x: 5.0, y: 5.0 };
        let absolute_position = Position { x: 10.0, y: 10.0 };
        let expected_location = MouseLocation::Absolute(absolute_position);

        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![fidl_input_report::InputReport {
            event_time: Some(event_time_i64),
            keyboard: None,
            mouse: Some(fidl_input_report::MouseInputReport {
                movement_x: Some(relative_movement.x as i64),
                movement_y: Some(relative_movement.y as i64),
                position_x: Some(absolute_position.x as i64),
                position_y: Some(absolute_position.y as i64),
                scroll_h: None,
                scroll_v: None,
                pressed_buttons: None,
                ..fidl_input_report::MouseInputReport::EMPTY
            }),
            touch: None,
            sensor: None,
            consumer_control: None,
            trace_id: None,
            ..fidl_input_report::InputReport::EMPTY
        }];
        let expected_events = vec![testing_utilities::create_mouse_event(
            expected_location,
            None, /* wheel_delta_v */
            None, /* wheel_delta_h */
            MousePhase::Move,
            HashSet::new(),
            HashSet::new(),
            event_time_u64,
            &descriptor,
        )];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that two separate button presses generate two separate down events with differing
    /// sets of `affected_buttons` and `pressed_buttons`.
    #[fasync::run_singlethreaded(test)]
    async fn down_down() {
        const PRIMARY_BUTTON: u8 = 1;
        const SECONDARY_BUTTON: u8 = 2;

        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![PRIMARY_BUTTON],
            event_time_i64,
        );
        let second_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![PRIMARY_BUTTON, SECONDARY_BUTTON],
            event_time_i64,
        );
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report, second_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![SECONDARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON, SECONDARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Tests that two staggered button presses followed by stagged releases generate four mouse
    /// events with distinct `affected_buttons` and `pressed_buttons`.
    /// Specifically, we test and expect the following in order:
    /// | Action           | MousePhase | `affected_buttons` | `pressed_buttons` |
    /// | ---------------- | ---------- | ------------------ | ----------------- |
    /// | Press button 1   | Down       | [1]                | [1]               |
    /// | Press button 2   | Down       | [2]                | [1, 2]            |
    /// | Release button 1 | Up         | [1]                | [2]               |
    /// | Release button 2 | Up         | [2]                | []                |
    #[fasync::run_singlethreaded(test)]
    async fn down_down_up_up() {
        const PRIMARY_BUTTON: u8 = 1;
        const SECONDARY_BUTTON: u8 = 2;

        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![PRIMARY_BUTTON],
            event_time_i64,
        );
        let second_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![PRIMARY_BUTTON, SECONDARY_BUTTON],
            event_time_i64,
        );
        let third_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![SECONDARY_BUTTON],
            event_time_i64,
        );
        let fourth_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![],
            event_time_i64,
        );
        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report, second_report, third_report, fourth_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![SECONDARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON, SECONDARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Up,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![SECONDARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Up,
                HashSet::from_iter(vec![SECONDARY_BUTTON].into_iter()),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Test simple scroll in vertical and horizontal.
    #[fasync::run_singlethreaded(test)]
    async fn scroll() {
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            Some(1),
            None,
            vec![],
            event_time_i64,
        );
        let second_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None,
            Some(1),
            vec![],
            event_time_i64,
        );

        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report, second_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                Some(1),
                None,
                MousePhase::Wheel,
                HashSet::new(),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None,
                Some(1),
                MousePhase::Wheel,
                HashSet::new(),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Test button down -> scroll -> button up -> continue scroll.
    #[fasync::run_singlethreaded(test)]
    async fn down_scroll_up_scroll() {
        const PRIMARY_BUTTON: u8 = 1;

        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![PRIMARY_BUTTON],
            event_time_i64,
        );
        let second_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            Some(1),
            None,
            vec![PRIMARY_BUTTON],
            event_time_i64,
        );
        let third_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            None, /* scroll_v */
            None, /* scroll_h */
            vec![],
            event_time_i64,
        );
        let fourth_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            Some(1),
            None,
            vec![],
            event_time_i64,
        );

        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report, second_report, third_report, fourth_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                Some(1),
                None,
                MousePhase::Wheel,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Up,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                Some(1),
                None,
                MousePhase::Wheel,
                HashSet::new(),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }

    /// Test button down with scroll -> button up with scroll -> scroll.
    #[fasync::run_singlethreaded(test)]
    async fn down_scroll_bundle_up_scroll_bundle() {
        const PRIMARY_BUTTON: u8 = 1;

        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            Some(1),
            None,
            vec![PRIMARY_BUTTON],
            event_time_i64,
        );
        let second_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            Some(1),
            None,
            vec![],
            event_time_i64,
        );
        let third_report = testing_utilities::create_mouse_input_report(
            MouseLocation::Relative(Default::default()),
            Some(1),
            None,
            vec![],
            event_time_i64,
        );

        let descriptor = mouse_device_descriptor(DEVICE_ID);

        let input_reports = vec![first_report, second_report, third_report];
        let expected_events = vec![
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Down,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                Some(1),
                None,
                MousePhase::Wheel,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                Some(1),
                None,
                MousePhase::Wheel,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                None, /* wheel_delta_v */
                None, /* wheel_delta_h */
                MousePhase::Up,
                HashSet::from_iter(vec![PRIMARY_BUTTON].into_iter()),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_mouse_event(
                MouseLocation::Relative(Default::default()),
                Some(1),
                None,
                MousePhase::Wheel,
                HashSet::new(),
                HashSet::new(),
                event_time_u64,
                &descriptor,
            ),
        ];

        assert_input_report_sequence_generates_events!(
            input_reports: input_reports,
            expected_events: expected_events,
            device_descriptor: descriptor,
            device_type: MouseBinding,
        );
    }
}
