// 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.

//! Implements applying keymaps to hardware keyboard key events.
//!
//! See [KeymapHandler] for details.

use crate::input_device;
use crate::input_handler::UnhandledInputHandler;
use crate::keyboard_binding;
use async_trait::async_trait;
use fuchsia_syslog::fx_log_debug;
use fuchsia_zircon as zx;
use keymaps;
use std::cell::RefCell;
use std::rc::Rc;

/// `KeymapHandler` applies a keymap to a keyboard event, resolving each key press
/// to a sequence of Unicode code points.  This allows basic keymap application,
/// but does not lend itself to generalized text editing.
///
/// Create a new one with [KeymapHandler::new].
#[derive(Debug, Default)]
pub struct KeymapHandler {
    /// Tracks the state of the modifier keys.
    modifier_state: RefCell<keymaps::ModifierState>,

    /// Tracks the lock state (NumLock, CapsLock).
    lock_state: RefCell<keymaps::LockStateKeys>,
}

/// This trait implementation allows the [KeymapHandler] to be hooked up into the input
/// pipeline.
#[async_trait(?Send)]
impl UnhandledInputHandler for KeymapHandler {
    async fn handle_unhandled_input_event(
        self: Rc<Self>,
        input_event: input_device::UnhandledInputEvent,
    ) -> Vec<input_device::InputEvent> {
        match input_event {
            // Decorate a keyboard event with key meaning.
            input_device::UnhandledInputEvent {
                device_event: input_device::InputDeviceEvent::Keyboard(event),
                device_descriptor,
                event_time,
                trace_id: _,
            } => vec![input_device::InputEvent::from(self.process_keyboard_event(
                event,
                device_descriptor,
                event_time,
            ))],
            // Pass other events unchanged.
            _ => vec![input_device::InputEvent::from(input_event)],
        }
    }
}

impl KeymapHandler {
    /// Creates a new instance of the keymap handler.
    pub fn new() -> Rc<Self> {
        Rc::new(Default::default())
    }

    /// Attaches a key meaning to each passing keyboard event.
    fn process_keyboard_event(
        self: &Rc<Self>,
        event: keyboard_binding::KeyboardEvent,
        device_descriptor: input_device::InputDeviceDescriptor,
        event_time: zx::Time,
    ) -> input_device::UnhandledInputEvent {
        let (key, event_type) = (event.get_key(), event.get_event_type());
        fx_log_debug!(
            concat!(
                "Keymap::process_keyboard_event: key:{:?}, ",
                "modifier_state:{:?}, lock_state: {:?}, event_type: {:?}"
            ),
            key,
            self.modifier_state.borrow(),
            self.lock_state.borrow(),
            event_type
        );

        self.modifier_state.borrow_mut().update(event_type, key);
        self.lock_state.borrow_mut().update(event_type, key);
        let key_meaning = keymaps::select_keymap(&event.get_keymap()).apply(
            key,
            &*self.modifier_state.borrow(),
            &*self.lock_state.borrow(),
        );
        input_device::UnhandledInputEvent {
            device_event: input_device::InputDeviceEvent::Keyboard(
                event.clone().into_with_key_meaning(key_meaning),
            ),
            device_descriptor,
            event_time,
            trace_id: None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{consumer_controls_binding, testing_utilities};
    use fuchsia_async as fasync;
    use fuchsia_zircon as zx;
    use pretty_assertions::assert_eq;
    use std::convert::TryFrom as _;

    // A mod-specific version of `testing_utilities::create_keyboard_event`.
    fn create_unhandled_keyboard_event(
        key: fidl_fuchsia_input::Key,
        event_type: fidl_fuchsia_ui_input3::KeyEventType,
        keymap: Option<String>,
    ) -> input_device::UnhandledInputEvent {
        let device_descriptor = input_device::InputDeviceDescriptor::Keyboard(
            keyboard_binding::KeyboardDeviceDescriptor {
                keys: vec![fidl_fuchsia_input::Key::A, fidl_fuchsia_input::Key::B],
            },
        );
        let (_, event_time_u64) = testing_utilities::event_times();
        input_device::UnhandledInputEvent::try_from(testing_utilities::create_keyboard_event(
            key,
            event_type,
            /* modifiers= */ None,
            event_time_u64,
            &device_descriptor,
            keymap,
        ))
        .unwrap()
    }

    // A mod-specific version of `testing_utilities::create_consumer_controls_event`.
    fn create_unhandled_consumer_controls_event(
        pressed_buttons: Vec<fidl_fuchsia_input_report::ConsumerControlButton>,
        event_time: zx::Time,
        device_descriptor: &input_device::InputDeviceDescriptor,
    ) -> input_device::UnhandledInputEvent {
        input_device::UnhandledInputEvent::try_from(
            testing_utilities::create_consumer_controls_event(
                pressed_buttons,
                event_time,
                device_descriptor,
            ),
        )
        .unwrap()
    }

    fn get_key_meaning(
        event: &input_device::InputEvent,
    ) -> Option<fidl_fuchsia_ui_input3::KeyMeaning> {
        match event {
            input_device::InputEvent {
                device_event: input_device::InputDeviceEvent::Keyboard(event),
                ..
            } => event.get_key_meaning(),
            _ => None,
        }
    }

    #[fasync::run_singlethreaded(test)]
    async fn test_keymap_application() {
        // Not using test_case crate because it does not compose very well with
        // async test execution.
        #[derive(Debug)]
        struct TestCase {
            events: Vec<input_device::UnhandledInputEvent>,
            expected: Vec<Option<fidl_fuchsia_ui_input3::KeyMeaning>>,
        }
        let tests: Vec<TestCase> = vec![
            TestCase {
                events: vec![create_unhandled_keyboard_event(
                    fidl_fuchsia_input::Key::A,
                    fidl_fuchsia_ui_input3::KeyEventType::Pressed,
                    Some("US_QWERTY".into()),
                )],
                expected: vec![
                    Some(fidl_fuchsia_ui_input3::KeyMeaning::Codepoint(97)), // a
                ],
            },
            TestCase {
                // A non-keyboard event.
                events: vec![create_unhandled_consumer_controls_event(
                    vec![],
                    zx::Time::ZERO,
                    &input_device::InputDeviceDescriptor::ConsumerControls(
                        consumer_controls_binding::ConsumerControlsDeviceDescriptor {
                            buttons: vec![],
                        },
                    ),
                )],
                expected: vec![None],
            },
            TestCase {
                events: vec![
                    create_unhandled_keyboard_event(
                        fidl_fuchsia_input::Key::LeftShift,
                        fidl_fuchsia_ui_input3::KeyEventType::Pressed,
                        Some("US_QWERTY".into()),
                    ),
                    create_unhandled_keyboard_event(
                        fidl_fuchsia_input::Key::A,
                        fidl_fuchsia_ui_input3::KeyEventType::Pressed,
                        Some("US_QWERTY".into()),
                    ),
                ],
                expected: vec![
                    Some(fidl_fuchsia_ui_input3::KeyMeaning::Codepoint(0)), // Shift...
                    Some(fidl_fuchsia_ui_input3::KeyMeaning::Codepoint(65)), // A
                ],
            },
            TestCase {
                events: vec![
                    create_unhandled_keyboard_event(
                        fidl_fuchsia_input::Key::Tab,
                        fidl_fuchsia_ui_input3::KeyEventType::Pressed,
                        Some("US_QWERTY".into()),
                    ),
                    create_unhandled_keyboard_event(
                        fidl_fuchsia_input::Key::A,
                        fidl_fuchsia_ui_input3::KeyEventType::Pressed,
                        Some("US_QWERTY".into()),
                    ),
                ],
                expected: vec![
                    Some(fidl_fuchsia_ui_input3::KeyMeaning::NonPrintableKey(
                        fidl_fuchsia_ui_input3::NonPrintableKey::Tab,
                    )),
                    Some(fidl_fuchsia_ui_input3::KeyMeaning::Codepoint(97)), // a
                ],
            },
        ];
        for test in &tests {
            let mut actual: Vec<Option<fidl_fuchsia_ui_input3::KeyMeaning>> = vec![];
            let handler = KeymapHandler::new();
            for event in &test.events {
                let mut result = handler
                    .clone()
                    .handle_unhandled_input_event(event.clone())
                    .await
                    .iter()
                    .map(get_key_meaning)
                    .collect();
                actual.append(&mut result);
            }
            assert_eq!(test.expected, actual);
        }
    }
}
