// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::input_device,
    crate::input_handler::UnhandledInputHandler,
    anyhow::Error,
    async_trait::async_trait,
    fidl_fuchsia_input::Key,
    fidl_fuchsia_ui_input3::{KeyEvent, KeyEventType, LockState, Modifiers},
    fidl_fuchsia_ui_shortcut as ui_shortcut, fuchsia_zircon as zx,
    std::rc::Rc,
};

pub struct ShortcutHandler {
    /// The proxy to the Shortcut manager service.
    manager: ui_shortcut::ManagerProxy,
}

#[async_trait(?Send)]
impl UnhandledInputHandler for ShortcutHandler {
    async fn handle_unhandled_input_event(
        self: Rc<Self>,
        unhandled_input_event: input_device::UnhandledInputEvent,
    ) -> Vec<input_device::InputEvent> {
        match unhandled_input_event {
            input_device::UnhandledInputEvent {
                device_event: input_device::InputDeviceEvent::Keyboard(ref keyboard_device_event),
                device_descriptor: input_device::InputDeviceDescriptor::Keyboard(_),
                event_time,
                trace_id: _,
            } => {
                let key_event = create_key_event(
                    &keyboard_device_event.get_key(),
                    keyboard_device_event.get_event_type().clone(),
                    keyboard_device_event.get_modifiers().clone(),
                    keyboard_device_event.get_lock_state().clone(),
                    event_time,
                );

                // If either pressed_keys or released_keys triggered a shortcut, consume the event
                let handled = handle_key_event(key_event, &self.manager).await;
                vec![input_device::InputEvent::from(unhandled_input_event).into_handled_if(handled)]
            }
            _ => vec![input_device::InputEvent::from(unhandled_input_event)],
        }
    }
}

impl ShortcutHandler {
    /// Creates a new [`ShortcutHandler`] and connects Keyboard and Shortcut services.
    pub fn new(shortcut_manager_proxy: ui_shortcut::ManagerProxy) -> Result<Rc<Self>, Error> {
        let handler = ShortcutHandler { manager: shortcut_manager_proxy };
        Ok(Rc::new(handler))
    }
}

/// Returns a KeyEvent with the given parameters.
///
/// # Parameters
/// `key`: The key associated with the KeyEvent.
/// `event_type`: The type of key, either pressed or released.
/// `modifiers`: The modifiers associated with the KeyEvent.
/// `lock_state`: The modifiers associated with the KeyEvent.
/// `event_time`: The time in nanoseconds when the event was first recorded.
fn create_key_event(
    key: &Key,
    event_type: KeyEventType,
    modifiers: Option<Modifiers>,
    lock_state: Option<LockState>,
    event_time: zx::Time,
) -> KeyEvent {
    KeyEvent {
        timestamp: Some(event_time.into_nanos()),
        type_: Some(event_type),
        key: Some(*key),
        modifiers,
        lock_state,
        ..KeyEvent::EMPTY
    }
}

/// Returns true if the Shortcut Manager handles the `key_event`.
///
/// # Parameters
/// `key_event`: The KeyEvent to handle by the Shortcut Manager.
/// `shortcut_manager`: The Shortcut Manager
async fn handle_key_event(
    key_event: KeyEvent,
    shortcut_manager: &ui_shortcut::ManagerProxy,
) -> bool {
    match shortcut_manager.handle_key3_event(key_event).await {
        Ok(true) => true,
        Ok(false) | Err(_) => false,
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*, crate::keyboard_binding, crate::testing_utilities,
        assert_matches::assert_matches, fidl_fuchsia_ui_input3 as fidl_ui_input3,
        fuchsia_async as fasync, fuchsia_zircon as zx, futures::StreamExt,
        pretty_assertions::assert_eq,
    };

    /// Creates an [`ShortcutHandler`] for tests.
    fn create_shortcut_handler(
        key_event_consumed_response: bool,
        _key2_event_consumed_response: bool,
    ) -> Rc<ShortcutHandler> {
        let (shortcut_manager_proxy, mut shortcut_manager_request_stream) =
            fidl::endpoints::create_proxy_and_stream::<ui_shortcut::ManagerMarker>()
                .expect("Failed to create ShortcutManagerProxy and stream");

        fuchsia_async::Task::local(async move {
            loop {
                match shortcut_manager_request_stream.next().await {
                    Some(Ok(ui_shortcut::ManagerRequest::HandleKey3Event {
                        event: _,
                        responder,
                        ..
                    })) => {
                        responder
                            .send(key_event_consumed_response)
                            .expect("error responding to HandleKeyEvent");
                    }
                    _ => assert!(false),
                }
            }
        })
        .detach();

        ShortcutHandler::new(shortcut_manager_proxy).expect("Failed to create ShortcutHandler.")
    }

    fn create_unhandled_keyboard_event(
        key3: fidl_fuchsia_input::Key,
        event_type: fidl_fuchsia_ui_input3::KeyEventType,
        modifiers: Option<fidl_ui_input3::Modifiers>,
        event_time: zx::Time,
    ) -> input_device::UnhandledInputEvent {
        let device_descriptor = input_device::InputDeviceDescriptor::Keyboard(
            keyboard_binding::KeyboardDeviceDescriptor { keys: vec![key3] },
        );
        let keyboard_event =
            keyboard_binding::KeyboardEvent::new(key3, event_type).into_with_modifiers(modifiers);
        input_device::UnhandledInputEvent {
            device_event: input_device::InputDeviceEvent::Keyboard(keyboard_event),
            device_descriptor,
            event_time,
            trace_id: None,
        }
    }

    /// Sends a pressed key event to the ShortcutHandler.
    async fn press_key(
        pressed_key3: fidl_fuchsia_input::Key,
        modifiers: Option<fidl_ui_input3::Modifiers>,
        event_time: zx::Time,
        shortcut_handler: Rc<ShortcutHandler>,
    ) -> Vec<input_device::InputEvent> {
        let input_event = create_unhandled_keyboard_event(
            pressed_key3,
            fidl_fuchsia_ui_input3::KeyEventType::Pressed,
            modifiers,
            event_time,
        );
        shortcut_handler.handle_unhandled_input_event(input_event).await
    }

    /// Sends a release key event to the ShortcutHandler.
    async fn release_key(
        released_key3: fidl_fuchsia_input::Key,
        modifiers: Option<fidl_ui_input3::Modifiers>,
        event_time: zx::Time,
        shortcut_handler: Rc<ShortcutHandler>,
    ) -> Vec<input_device::InputEvent> {
        let input_event = create_unhandled_keyboard_event(
            released_key3,
            fidl_fuchsia_ui_input3::KeyEventType::Released,
            modifiers,
            event_time,
        );
        shortcut_handler.handle_unhandled_input_event(input_event).await
    }

    /// Tests that a press key event is not consumed if it is not a shortcut.
    #[fasync::run_singlethreaded(test)]
    async fn press_key_no_shortcut() {
        let shortcut_handler = create_shortcut_handler(false, false);
        let modifiers = None;
        let key3 = fidl_fuchsia_input::Key::A;
        let event_time = zx::Time::get_monotonic();

        let handle_result = press_key(key3, modifiers, event_time, shortcut_handler).await;
        assert_matches!(
            handle_result.as_slice(),
            [input_device::InputEvent { handled: input_device::Handled::No, .. }]
        );

        let device_descriptor = input_device::InputDeviceDescriptor::Keyboard(
            keyboard_binding::KeyboardDeviceDescriptor { keys: vec![key3] },
        );
        let input_event = testing_utilities::create_keyboard_event(
            key3,
            fidl_fuchsia_ui_input3::KeyEventType::Pressed,
            modifiers,
            event_time,
            &device_descriptor,
            /* keymap= */ None,
        );

        assert_eq!(handle_result[0], input_event);
    }

    /// Tests that a press key shortcut is consumed.
    #[fasync::run_singlethreaded(test)]
    async fn press_key_activates_shortcut() {
        let event_time = zx::Time::get_monotonic();
        let shortcut_handler = create_shortcut_handler(true, false);
        let handle_result = press_key(
            fidl_fuchsia_input::Key::CapsLock,
            Some(fidl_ui_input3::Modifiers::CAPS_LOCK),
            event_time,
            shortcut_handler,
        )
        .await;
        assert_matches!(
            handle_result.as_slice(),
            [input_device::InputEvent { handled: input_device::Handled::Yes, .. }]
        );
    }

    /// Tests that a release key event is not consumed if it is not a shortcut.
    #[fasync::run_singlethreaded(test)]
    async fn release_key_no_shortcut() {
        let shortcut_handler = create_shortcut_handler(false, false);
        let key3 = fidl_fuchsia_input::Key::A;
        let modifiers = None;
        let event_time = zx::Time::get_monotonic();

        let handle_result = release_key(key3, modifiers, event_time, shortcut_handler).await;
        assert_matches!(
            handle_result.as_slice(),
            [input_device::InputEvent { handled: input_device::Handled::No, .. }]
        );

        let device_descriptor = input_device::InputDeviceDescriptor::Keyboard(
            keyboard_binding::KeyboardDeviceDescriptor { keys: vec![key3] },
        );
        let input_event = testing_utilities::create_keyboard_event(
            key3,
            fidl_fuchsia_ui_input3::KeyEventType::Released,
            modifiers,
            event_time,
            &device_descriptor,
            /* keymap= */ None,
        );

        assert_eq!(handle_result[0], input_event);
    }

    /// Tests that a release key event triggers a registered shortcut.
    #[fasync::run_singlethreaded(test)]
    async fn release_key_triggers_shortcut() {
        let shortcut_handler = create_shortcut_handler(true, false);
        let event_time = zx::Time::get_monotonic();

        let handle_result = release_key(
            fidl_fuchsia_input::Key::CapsLock,
            Some(fidl_ui_input3::Modifiers::CAPS_LOCK),
            event_time,
            shortcut_handler,
        )
        .await;
        assert_matches!(
            handle_result.as_slice(),
            [input_device::InputEvent { handled: input_device::Handled::Yes, .. }]
        );
    }
}
