// Copyright 2021 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},
    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,
};

/// A [`ConsumerControlsEvent`] represents an event where one or more consumer control buttons
/// were pressed.
///
/// # Example
/// The following ConsumerControlsEvents represents an event where the volume up button was pressed.
///
/// ```
/// let volume_event = input_device::InputDeviceEvent::ConsumerControls(ConsumerControlsEvent::new(
///     vec![fidl_input_report::ConsumerControlButton::VOLUME_UP],
/// ));
/// ```
#[derive(Clone, Debug, PartialEq)]
pub struct ConsumerControlsEvent {
    pub pressed_buttons: Vec<fidl_input_report::ConsumerControlButton>,
}

impl ConsumerControlsEvent {
    /// Creates a new [`ConsumerControlsEvent`] with the relevant buttons.
    ///
    /// # Parameters
    /// - `pressed_buttons`: The buttons relevant to this event.
    pub fn new(pressed_buttons: Vec<fidl_input_report::ConsumerControlButton>) -> Self {
        Self { pressed_buttons }
    }
}

/// A [`ConsumerControlsBinding`] represents a connection to a consumer controls input device with
/// consumer controls. The buttons supported by this binding is returned by `supported_buttons()`.
///
/// The [`ConsumerControlsBinding`] parses and exposes consumer control descriptor properties
/// 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 ConsumerControlsBinding {
    /// The channel to stream InputEvents to.
    event_sender: Sender<input_device::InputEvent>,

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

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ConsumerControlsDeviceDescriptor {
    /// The list of buttons that this device contains.
    pub buttons: Vec<fidl_input_report::ConsumerControlButton>,
}

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

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

impl ConsumerControlsBinding {
    /// 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.
    /// - `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,
        input_event_sender: Sender<input_device::InputEvent>,
    ) -> Result<Self, Error> {
        let device_binding = Self::bind_device(&device_proxy, 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.
    /// - `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,
        input_event_sender: Sender<input_device::InputEvent>,
    ) -> Result<Self, Error> {
        let device_descriptor: fidl_input_report::DeviceDescriptor =
            device.get_descriptor().await?;

        let consumer_controls_descriptor = device_descriptor.consumer_control.ok_or_else(|| {
            format_err!("DeviceDescriptor does not have a ConsumerControlDescriptor")
        })?;

        let consumer_controls_input_descriptor =
            consumer_controls_descriptor.input.ok_or_else(|| {
                format_err!(
                    "ConsumerControlDescriptor does not have a ConsumerControlInputDescriptor"
                )
            })?;

        let device_descriptor: ConsumerControlsDeviceDescriptor =
            ConsumerControlsDeviceDescriptor {
                buttons: consumer_controls_input_descriptor.buttons.unwrap_or_default(),
            };

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

    /// Parses an [`InputReport`] into one or more [`InputEvent`]s. Sends the [`InputEvent`]s
    /// 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 ConsumerControlInputReport.
        let pressed_buttons: Vec<fidl_input_report::ConsumerControlButton> =
            match report.consumer_control {
                Some(ref consumer_control_report) => consumer_control_report
                    .pressed_buttons
                    .as_ref()
                    .map(|buttons| buttons.iter().cloned().collect())
                    .unwrap_or_default(),
                None => return previous_report,
            };

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

        send_consumer_controls_event(
            pressed_buttons,
            device_descriptor,
            event_time,
            input_event_sender,
        );

        Some(report)
    }
}

/// Sends an InputEvent over `sender`.
///
/// # Parameters
/// - `pressed_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 InputEvent to.
fn send_consumer_controls_event(
    pressed_buttons: Vec<fidl_input_report::ConsumerControlButton>,
    device_descriptor: &input_device::InputDeviceDescriptor,
    event_time: zx::Time,
    sender: &mut Sender<input_device::InputEvent>,
) {
    if let Err(e) = sender.try_send(input_device::InputEvent {
        device_event: input_device::InputDeviceEvent::ConsumerControls(ConsumerControlsEvent::new(
            pressed_buttons,
        )),
        device_descriptor: device_descriptor.clone(),
        event_time,
        handled: Handled::No,
        trace_id: None,
    }) {
        fx_log_err!("Failed to send ConsumerControlsEvent with error: {:?}", e);
    }
}

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

    // Tests that an InputReport containing one consumer control button generates an InputEvent
    // containing the same consumer control button.
    #[fasync::run_singlethreaded(test)]
    async fn volume_up_only() {
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let pressed_buttons = vec![fidl_input_report::ConsumerControlButton::VolumeUp];
        let first_report = testing_utilities::create_consumer_control_input_report(
            pressed_buttons.clone(),
            event_time_i64,
        );
        let descriptor = testing_utilities::consumer_controls_device_descriptor();

        let input_reports = vec![first_report];
        let expected_events = vec![testing_utilities::create_consumer_controls_event(
            pressed_buttons,
            event_time_u64,
            &descriptor,
        )];

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

    // Tests that an InputReport containing two consumer control buttons generates an InputEvent
    // containing both consumer control buttons.
    #[fasync::run_singlethreaded(test)]
    async fn volume_up_and_down() {
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let pressed_buttons = vec![
            fidl_input_report::ConsumerControlButton::VolumeUp,
            fidl_input_report::ConsumerControlButton::VolumeDown,
        ];
        let first_report = testing_utilities::create_consumer_control_input_report(
            pressed_buttons.clone(),
            event_time_i64,
        );
        let descriptor = testing_utilities::consumer_controls_device_descriptor();

        let input_reports = vec![first_report];
        let expected_events = vec![testing_utilities::create_consumer_controls_event(
            pressed_buttons,
            event_time_u64,
            &descriptor,
        )];

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

    // Tests that three InputReports containing one consumer control button generates three
    // InputEvents containing the same consumer control button.
    #[fasync::run_singlethreaded(test)]
    async fn sequence_of_buttons() {
        let (event_time_i64, event_time_u64) = testing_utilities::event_times();
        let first_report = testing_utilities::create_consumer_control_input_report(
            vec![fidl_input_report::ConsumerControlButton::VolumeUp],
            event_time_i64,
        );
        let second_report = testing_utilities::create_consumer_control_input_report(
            vec![fidl_input_report::ConsumerControlButton::VolumeDown],
            event_time_i64,
        );
        let third_report = testing_utilities::create_consumer_control_input_report(
            vec![fidl_input_report::ConsumerControlButton::CameraDisable],
            event_time_i64,
        );
        let descriptor = testing_utilities::consumer_controls_device_descriptor();

        let input_reports = vec![first_report, second_report, third_report];
        let expected_events = vec![
            testing_utilities::create_consumer_controls_event(
                vec![fidl_input_report::ConsumerControlButton::VolumeUp],
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_consumer_controls_event(
                vec![fidl_input_report::ConsumerControlButton::VolumeDown],
                event_time_u64,
                &descriptor,
            ),
            testing_utilities::create_consumer_controls_event(
                vec![fidl_input_report::ConsumerControlButton::CameraDisable],
                event_time_u64,
                &descriptor,
            ),
        ];

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