// 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 {
    anyhow::{format_err, Error, Result},
    fidl_fuchsia_input as input, fidl_fuchsia_ui_input as ui_input,
    fidl_fuchsia_ui_input3::{self as ui_input3, LockState, Modifiers},
    keymaps::{usages::input3_key_to_hid_usage, LockStateKeys, ModifierState},
    std::collections::HashSet,
};

const EMPTY_TIME: u64 = 0;
const EMPTY_DEVICE_ID: u32 = 0;

const HID_USAGE_NO_EVENT: u32 = 0;

// Type of a keyboard event.
#[derive(Debug, Clone)]
pub(crate) enum KeyEventType {
    Pressed,
    Released,
}

/// A key and/or key meaning inside a `KeyEvent`. At least one of the two must be present.
#[derive(Debug, Clone)]
enum KeyOrMeaning {
    Key(input::Key),
    Meaning(ui_input3::KeyMeaning),
    Both(input::Key, ui_input3::KeyMeaning),
}

impl KeyOrMeaning {
    fn key(&self) -> Option<input::Key> {
        match self {
            KeyOrMeaning::Key(key) => Some(*key),
            KeyOrMeaning::Both(key, _) => Some(*key),
            _ => None,
        }
    }

    fn key_meaning(&self) -> Option<ui_input3::KeyMeaning> {
        match self {
            KeyOrMeaning::Meaning(meaning) => Some(*meaning),
            KeyOrMeaning::Both(_, meaning) => Some(*meaning),
            _ => None,
        }
    }

    fn code_point(&self) -> Option<u32> {
        self.key_meaning().and_then(|key_meaning| match key_meaning {
            ui_input3::KeyMeaning::Codepoint(code_point) => Some(code_point),
            _ => None,
        })
    }
}

/// Abstraction wrapper for a key event.
#[derive(Debug, Clone)]
pub(crate) struct KeyEvent {
    /// Key or key meaning that triggered the event.
    key_or_meaning: KeyOrMeaning,

    /// Keys pressed at the time of the event.
    ///
    /// (Note: This is used for determining active modifiers. Knowing which key meanings are pressed
    /// is not currently needed.)
    pub keys_pressed: HashSet<input::Key>,

    pub type_: KeyEventType,

    inner: Option<ui_input3::KeyEvent>,
}

impl KeyEvent {
    pub fn new(
        event: &ui_input3::KeyEvent,
        keys_pressed: HashSet<input::Key>,
    ) -> Result<Self, Error> {
        let (key, meaning) = (event.key, event.key_meaning);
        let key_or_meaning = match (key, meaning) {
            (None, Some(meaning)) => KeyOrMeaning::Meaning(meaning),
            (Some(key), None) => KeyOrMeaning::Key(key),
            (Some(key), Some(meaning)) => KeyOrMeaning::Both(key, meaning),
            // This branch exists because there is no way to enforce the "at least one of the two"
            // requirement in the current FIDL schema.
            (None, None) => return Err(format_err!("Missing key and key_meaning: {:?}", event)),
        };

        let type_ = match event.type_ {
            Some(ui_input3::KeyEventType::Pressed) => KeyEventType::Pressed,
            Some(ui_input3::KeyEventType::Released) => KeyEventType::Released,
            _ => return Err(format_err!("Unsupported event type")),
        };
        Ok(Self { inner: Some(event.clone()), key_or_meaning, keys_pressed, type_ })
    }

    pub fn key(&self) -> Option<input::Key> {
        self.key_or_meaning.key()
    }

    pub fn code_point(&self) -> Option<u32> {
        self.key_or_meaning.code_point()
    }
}

impl TryFrom<KeyEvent> for ui_input::KeyboardEvent {
    type Error = Error;

    /// Attempts to convert KeyEvent into fidl_fuchsia_ui_input::KeyboardEvent.
    /// This will produce single event with the best effort using the data available.
    /// Data fields that are not possible to express in a single `KeyboardEvent` are
    /// ignored: e.g. NumLock and ScrollLock modifiers.
    /// USB HID usage codes outside of QWERTY keyboard layout generate errors.
    fn try_from(event: KeyEvent) -> Result<Self, Error> {
        let inner = event
            .inner
            .as_ref()
            .ok_or(format_err!("Need underlying input3 event for conversion."))?;
        let phase = match event.type_ {
            KeyEventType::Pressed => ui_input::KeyboardEventPhase::Pressed,
            KeyEventType::Released => ui_input::KeyboardEventPhase::Released,
        };

        let caps_lock = match inner.modifiers {
            Some(modifiers) if modifiers.contains(ui_input3::Modifiers::CAPS_LOCK) => {
                ui_input::MODIFIER_CAPS_LOCK
            }
            _ => ui_input::MODIFIER_NONE,
        };
        let left_shift = if event.keys_pressed.contains(&input::Key::LeftShift) {
            ui_input::MODIFIER_LEFT_SHIFT
        } else {
            ui_input::MODIFIER_NONE
        };
        let right_shift = if event.keys_pressed.contains(&input::Key::RightShift) {
            ui_input::MODIFIER_RIGHT_SHIFT
        } else {
            ui_input::MODIFIER_NONE
        };
        let left_control = if event.keys_pressed.contains(&input::Key::LeftCtrl) {
            ui_input::MODIFIER_LEFT_CONTROL
        } else {
            ui_input::MODIFIER_NONE
        };
        let right_control = if event.keys_pressed.contains(&input::Key::RightCtrl) {
            ui_input::MODIFIER_RIGHT_CONTROL
        } else {
            ui_input::MODIFIER_NONE
        };
        let left_alt = if event.keys_pressed.contains(&input::Key::LeftAlt) {
            ui_input::MODIFIER_LEFT_ALT
        } else {
            ui_input::MODIFIER_NONE
        };
        let right_alt = if event.keys_pressed.contains(&input::Key::RightAlt) {
            ui_input::MODIFIER_RIGHT_ALT
        } else {
            ui_input::MODIFIER_NONE
        };
        let left_super = if event.keys_pressed.contains(&input::Key::LeftMeta) {
            ui_input::MODIFIER_LEFT_SUPER
        } else {
            ui_input::MODIFIER_NONE
        };
        let right_super = if event.keys_pressed.contains(&input::Key::RightMeta) {
            ui_input::MODIFIER_RIGHT_SUPER
        } else {
            ui_input::MODIFIER_NONE
        };

        // TODO(https://fxbug.dev/42156751): Should `NonPrintableKey`s be converted to hid_usage when key is
        // missing?
        let hid_usage = match event.key() {
            Some(key) => input3_key_to_hid_usage(key),
            None => HID_USAGE_NO_EVENT,
        };

        let code_point = match event.code_point() {
            Some(code_point) => code_point,
            None => keymaps::US_QWERTY.hid_usage_to_code_point(
                hid_usage,
                &ModifierState::new()
                    .with_if(Modifiers::LEFT_SHIFT, left_shift == ui_input::MODIFIER_LEFT_SHIFT)
                    .with_if(Modifiers::RIGHT_SHIFT, right_shift == ui_input::MODIFIER_RIGHT_SHIFT),
                &LockStateKeys::new()
                    .with_if(LockState::CAPS_LOCK, caps_lock == ui_input::MODIFIER_CAPS_LOCK),
            )?,
        };
        Ok(ui_input::KeyboardEvent {
            event_time: inner.timestamp.unwrap_or(EMPTY_TIME as i64) as u64,
            device_id: EMPTY_DEVICE_ID,
            phase,
            hid_usage,
            code_point,
            modifiers: caps_lock
                | left_shift
                | right_shift
                | left_control
                | right_control
                | left_alt
                | right_alt
                | left_super
                | right_super,
        })
    }
}

impl TryFrom<KeyEvent> for ui_input3::KeyEvent {
    type Error = Error;

    /// Attempts to convert KeyEvent into `fidl_fuchsia_ui_input3::KeyEvent`.
    fn try_from(event: KeyEvent) -> Result<Self, Error> {
        event.inner.ok_or(format_err!("Need underlying input3 event for conversion."))
    }
}

#[cfg(test)]
mod test {
    use {super::*, fuchsia_zircon as zx, keymaps::usages::Usages, maplit::hashset};

    static TEST_TIMESTAMP: i64 = 123;

    #[test]
    fn event_all_locks() -> Result<(), Error> {
        let event = ui_input3::KeyEvent {
            timestamp: Some(TEST_TIMESTAMP),
            type_: Some(ui_input3::KeyEventType::Pressed),
            key: Some(input::Key::A),
            modifiers: Some(
                ui_input3::Modifiers::CAPS_LOCK
                    | ui_input3::Modifiers::NUM_LOCK
                    | ui_input3::Modifiers::SCROLL_LOCK,
            ),
            ..Default::default()
        };

        let key_event = KeyEvent::new(&event, HashSet::new())?;

        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(
            keyboard_event,
            ui_input::KeyboardEvent {
                event_time: TEST_TIMESTAMP as u64,
                device_id: EMPTY_DEVICE_ID,
                phase: ui_input::KeyboardEventPhase::Pressed,
                hid_usage: Usages::HidUsageKeyA as u32,
                code_point: 'A' as u32,
                modifiers: ui_input::MODIFIER_CAPS_LOCK,
            }
        );
        Ok(())
    }

    #[test]
    fn event_all_modifiers() -> Result<(), Error> {
        let event = ui_input3::KeyEvent {
            type_: Some(ui_input3::KeyEventType::Pressed),
            key: Some(input::Key::B),
            modifiers: Some(
                ui_input3::Modifiers::CAPS_LOCK
                    | ui_input3::Modifiers::NUM_LOCK
                    | ui_input3::Modifiers::SCROLL_LOCK,
            ),
            ..Default::default()
        };

        let key_event = KeyEvent::new(
            &event,
            HashSet::from_iter(vec![
                input::Key::LeftShift,
                input::Key::RightShift,
                input::Key::LeftCtrl,
                input::Key::RightCtrl,
                input::Key::LeftAlt,
                input::Key::RightAlt,
                input::Key::LeftMeta,
                input::Key::RightMeta,
            ]),
        )?;

        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(
            keyboard_event,
            ui_input::KeyboardEvent {
                event_time: EMPTY_TIME,
                device_id: EMPTY_DEVICE_ID,
                phase: ui_input::KeyboardEventPhase::Pressed,
                hid_usage: Usages::HidUsageKeyB as u32,
                code_point: 'B' as u32,
                modifiers: ui_input::MODIFIER_CAPS_LOCK
                    | ui_input::MODIFIER_LEFT_SHIFT
                    | ui_input::MODIFIER_RIGHT_SHIFT
                    | ui_input::MODIFIER_LEFT_CONTROL
                    | ui_input::MODIFIER_RIGHT_CONTROL
                    | ui_input::MODIFIER_LEFT_ALT
                    | ui_input::MODIFIER_RIGHT_ALT
                    | ui_input::MODIFIER_LEFT_SUPER
                    | ui_input::MODIFIER_RIGHT_SUPER,
            }
        );
        Ok(())
    }

    #[test]
    fn event_no_modifiers() -> Result<(), Error> {
        let event = ui_input3::KeyEvent {
            key: Some(input::Key::C),
            type_: Some(ui_input3::KeyEventType::Pressed),
            ..Default::default()
        };

        let key_event = KeyEvent::new(&event, HashSet::new())?;

        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(
            keyboard_event,
            ui_input::KeyboardEvent {
                event_time: EMPTY_TIME,
                device_id: EMPTY_DEVICE_ID,
                phase: ui_input::KeyboardEventPhase::Pressed,
                hid_usage: Usages::HidUsageKeyC as u32,
                code_point: 'c' as u32,
                modifiers: ui_input::MODIFIER_NONE,
            }
        );
        Ok(())
    }

    #[test]
    fn event_code_point_only() -> Result<(), Error> {
        let event = test_helpers::create_key_event(
            zx::Time::ZERO,
            ui_input3::KeyEventType::Pressed,
            None,
            None,
            'й',
        );

        let key_event = KeyEvent::new(&event, HashSet::new())?;

        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(
            keyboard_event,
            ui_input::KeyboardEvent {
                event_time: EMPTY_TIME,
                device_id: EMPTY_DEVICE_ID,
                phase: ui_input::KeyboardEventPhase::Pressed,
                hid_usage: HID_USAGE_NO_EVENT as u32,
                code_point: 'й' as u32,
                modifiers: ui_input::MODIFIER_NONE,
            }
        );
        Ok(())
    }

    #[test]
    fn event_code_point_only_unaffected_by_modifier_keys() -> Result<(), Error> {
        let event = test_helpers::create_key_event(
            zx::Time::ZERO,
            ui_input3::KeyEventType::Pressed,
            None,
            None,
            'й',
        );

        let key_event = KeyEvent::new(&event, hashset!(input::Key::RightShift))?;

        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(
            keyboard_event,
            ui_input::KeyboardEvent {
                event_time: EMPTY_TIME,
                device_id: EMPTY_DEVICE_ID,
                phase: ui_input::KeyboardEventPhase::Pressed,
                hid_usage: HID_USAGE_NO_EVENT as u32,
                code_point: 'й' as u32,
                modifiers: ui_input::MODIFIER_RIGHT_SHIFT,
            }
        );
        Ok(())
    }

    #[test]
    fn event_non_printable_key_meaning_only() -> Result<(), Error> {
        let event = test_helpers::create_key_event(
            zx::Time::ZERO,
            ui_input3::KeyEventType::Pressed,
            None,
            None,
            ui_input3::NonPrintableKey::Backspace,
        );

        let key_event = KeyEvent::new(&event, HashSet::new())?;

        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(
            keyboard_event,
            ui_input::KeyboardEvent {
                event_time: EMPTY_TIME,
                device_id: EMPTY_DEVICE_ID,
                phase: ui_input::KeyboardEventPhase::Pressed,
                hid_usage: HID_USAGE_NO_EVENT as u32,
                code_point: 0,
                modifiers: ui_input::MODIFIER_NONE,
            }
        );
        Ok(())
    }

    #[test]
    fn event_key_released() -> Result<(), Error> {
        let event = ui_input3::KeyEvent {
            key: Some(input::Key::D),
            type_: Some(ui_input3::KeyEventType::Released),
            ..Default::default()
        };

        let key_event = KeyEvent::new(&event, HashSet::new())?;

        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(
            keyboard_event,
            ui_input::KeyboardEvent {
                event_time: EMPTY_TIME,
                device_id: EMPTY_DEVICE_ID,
                phase: ui_input::KeyboardEventPhase::Released,
                hid_usage: Usages::HidUsageKeyD as u32,
                code_point: 'd' as u32,
                modifiers: ui_input::MODIFIER_NONE,
            }
        );
        Ok(())
    }

    #[test]
    fn key_or_meaning_required() -> Result<(), Error> {
        let event = ui_input3::KeyEvent {
            type_: Some(ui_input3::KeyEventType::Pressed),
            ..Default::default()
        };

        let key_event = KeyEvent::new(&event, HashSet::new());
        assert!(key_event.is_err());
        Ok(())
    }

    #[test]
    fn key_meaning_alone_is_sufficient() -> Result<(), Error> {
        let event = test_helpers::create_key_event(
            zx::Time::ZERO,
            ui_input3::KeyEventType::Pressed,
            None,
            None,
            'й',
        );

        let key_event = KeyEvent::new(&event, HashSet::new());
        assert!(key_event.is_ok());
        Ok(())
    }

    #[test]
    fn type_required() -> Result<(), Error> {
        let event = ui_input3::KeyEvent { key: Some(input::Key::E), ..Default::default() };

        let key_event = KeyEvent::new(&event, HashSet::new());
        assert!(key_event.is_err());
        Ok(())
    }

    #[test]
    fn sync_not_supported() -> Result<(), Error> {
        let event = ui_input3::KeyEvent {
            type_: Some(ui_input3::KeyEventType::Sync),
            key: Some(input::Key::E),
            ..Default::default()
        };

        let key_event = KeyEvent::new(&event, HashSet::new());
        assert!(key_event.is_err());
        Ok(())
    }

    #[test]
    fn cancel_not_supported() -> Result<(), Error> {
        let event = ui_input3::KeyEvent {
            type_: Some(ui_input3::KeyEventType::Cancel),
            key: Some(input::Key::E),
            ..Default::default()
        };
        let key_event = KeyEvent::new(&event, HashSet::new());
        assert!(key_event.is_err());
        Ok(())
    }

    #[test]
    fn non_modifier_keys_pressed_ignored() -> Result<(), Error> {
        let event = ui_input3::KeyEvent {
            key: Some(input::Key::F),
            type_: Some(ui_input3::KeyEventType::Pressed),
            ..Default::default()
        };

        let key_event =
            KeyEvent::new(&event, HashSet::from_iter(vec![input::Key::G, input::Key::H]))?;

        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(
            keyboard_event,
            ui_input::KeyboardEvent {
                event_time: EMPTY_TIME,
                device_id: EMPTY_DEVICE_ID,
                phase: ui_input::KeyboardEventPhase::Pressed,
                hid_usage: Usages::HidUsageKeyF as u32,
                code_point: 'f' as u32,
                modifiers: ui_input::MODIFIER_NONE,
            }
        );
        Ok(())
    }

    #[test]
    fn explicit_code_point_overrides_calculated_code_point() -> Result<(), Error> {
        let event = test_helpers::create_key_event(
            zx::Time::ZERO,
            ui_input3::KeyEventType::Pressed,
            input::Key::Q,
            None,
            'й',
        );
        let key_event = KeyEvent::new(&event, HashSet::new())?;
        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(keyboard_event.code_point, 'й' as u32);

        Ok(())
    }

    #[test]
    fn calculated_code_point_is_preserved_with_non_printable_key_meaning() -> Result<(), Error> {
        let event = test_helpers::create_key_event(
            zx::Time::ZERO,
            ui_input3::KeyEventType::Pressed,
            input::Key::Q,
            ui_input3::Modifiers::CAPS_LOCK,
            ui_input3::NonPrintableKey::Tab,
        );
        let key_event = KeyEvent::new(&event, HashSet::new())?;
        let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
        assert_eq!(keyboard_event.code_point, 'Q' as u32);

        Ok(())
    }

    #[test]
    fn empty_codepoint() -> Result<(), Error> {
        let keys = &[
            (input::Key::LeftShift, Usages::HidUsageKeyLeftShift as u32),
            (input::Key::Enter, Usages::HidUsageKeyEnter as u32),
        ];
        for &(key1, key2) in keys {
            let event = ui_input3::KeyEvent {
                key: Some(key1),
                type_: Some(ui_input3::KeyEventType::Pressed),
                ..Default::default()
            };

            let key_event = KeyEvent::new(&event, HashSet::new())?;

            let keyboard_event: ui_input::KeyboardEvent = key_event.try_into()?;
            assert_eq!(
                keyboard_event,
                ui_input::KeyboardEvent {
                    event_time: EMPTY_TIME,
                    device_id: EMPTY_DEVICE_ID,
                    phase: ui_input::KeyboardEventPhase::Pressed,
                    hid_usage: key2,
                    code_point: 0,
                    modifiers: ui_input::MODIFIER_NONE,
                }
            );
        }
        Ok(())
    }
}
