// Copyright 2018 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::ime_service::ImeService;
use failure::ResultExt;
use fidl::encoding::OutOfLine;
use fidl::endpoints::RequestStream;
use fidl_fuchsia_ui_input as uii;
use fidl_fuchsia_ui_input::InputMethodEditorRequest as ImeReq;
use fidl_fuchsia_ui_text as txt;
use fuchsia_syslog::{fx_log_err, fx_log_warn};
use futures::prelude::*;
use lazy_static::lazy_static;
use parking_lot::Mutex;
use regex::Regex;
use std::char;
use std::collections::HashMap;
use std::ops::Range;
use std::sync::{Arc, Weak};
use unicode_segmentation::{GraphemeCursor, UnicodeSegmentation};

// TODO(lard): move constants into common, centralized location?
pub const HID_USAGE_KEY_BACKSPACE: u32 = 0x2a;
pub const HID_USAGE_KEY_RIGHT: u32 = 0x4f;
pub const HID_USAGE_KEY_LEFT: u32 = 0x50;
pub const HID_USAGE_KEY_ENTER: u32 = 0x28;
pub const HID_USAGE_KEY_DELETE: u32 = 0x2e;

/// The internal state of the IME, usually held within the IME behind an Arc<Mutex>
/// so it can be accessed from multiple places.
pub struct ImeState {
    text_state: uii::TextInputState,

    /// A handle to call methods on the text field.
    client: Box<uii::InputMethodEditorClientProxyInterface>,

    keyboard_type: uii::KeyboardType,
    action: uii::InputMethodAction,
    ime_service: ImeService,

    /// We expose a TextField interface to an input method. There are also legacy
    /// input methods that just send key events through inject_input — in this case,
    /// input_method would be None, and these events would be handled by the
    /// inject_input method. ImeState can only handle talking to one input_method
    /// at a time; it's the responsibility of some other code (likely inside
    /// ImeService) to multiplex multiple TextField interfaces into this one.
    input_method: Option<txt::TextFieldControlHandle>,

    /// A number used to serve the TextField interface. It increments any time any
    /// party makes a change to the state.
    revision: u64,

    /// A TextPoint is a u64 token that represents a character position in the new
    /// TextField interface. Each token is a unique ID; this represents the ID we
    /// will assign to the next TextPoint that is created. It increments every time
    /// a TextPoint is created. This is never reset, even when TextPoints are
    /// invalidated; TextPoints have globally unique IDs.
    next_text_point_id: u64,

    /// A TextPoint is a u64 token that represents a character position in the new
    /// TextField interface. This maps TextPoint IDs to byte indexes inside
    /// `text_state.text`. When a new revision is created, all preexisting TextPoints
    /// are deleted, which means we clear this out.
    text_points: HashMap<u64, usize>,
}

/// A service that talks to a text field, providing it edits and cursor state updates
/// in response to user input.
#[derive(Clone)]
pub struct Ime(Arc<Mutex<ImeState>>);

impl Ime {
    pub fn new<I: 'static + uii::InputMethodEditorClientProxyInterface>(
        keyboard_type: uii::KeyboardType,
        action: uii::InputMethodAction,
        initial_state: uii::TextInputState,
        client: I,
        ime_service: ImeService,
    ) -> Ime {
        let state = ImeState {
            text_state: initial_state,
            client: Box::new(client),
            keyboard_type,
            action,
            ime_service,
            revision: 0,
            next_text_point_id: 0,
            text_points: HashMap::new(),
            input_method: None,
        };
        Ime(Arc::new(Mutex::new(state)))
    }

    pub fn downgrade(&self) -> Weak<Mutex<ImeState>> {
        Arc::downgrade(&self.0)
    }

    pub fn upgrade(weak: &Weak<Mutex<ImeState>>) -> Option<Ime> {
        weak.upgrade().map(|arc| Ime(arc))
    }

    pub fn bind_text_field(&self, mut stream: txt::TextFieldRequestStream) {
        let control_handle = stream.control_handle();
        {
            let mut state = self.0.lock();
            let res = control_handle.send_on_update(&mut state.as_text_field_state());
            if let Err(e) = res {
                fx_log_err!("{}", e);
            } else {
                state.input_method = Some(control_handle);
            }
        }
        let self_clone = self.clone();
        fuchsia_async::spawn(
            async move {
                while let Some(msg) = await!(stream.try_next())
                    .context("error reading value from text field request stream")?
                {
                    if let Err(e) = self_clone.handle_text_field_msg(msg) {
                        fx_log_err!("Error when replying to TextFieldRequest: {}", e);
                    }
                }
                Ok(())
            }
                .unwrap_or_else(|e: failure::Error| fx_log_err!("{:?}", e)),
        );
    }

    pub fn bind_ime(&self, chan: fuchsia_async::Channel) {
        let self_clone = self.clone();
        let self_clone_2 = self.clone();
        fuchsia_async::spawn(
            async move {
                let mut stream = uii::InputMethodEditorRequestStream::from_channel(chan);
                while let Some(msg) = await!(stream.try_next())
                    .context("error reading value from IME request stream")?
                {
                    self_clone.handle_ime_message(msg);
                }
                Ok(())
            }
                .unwrap_or_else(|e: failure::Error| fx_log_err!("{:?}", e))
                .then(async move |()| {
                    // this runs when IME stream closes
                    // clone to ensure we only hold one lock at a time
                    let ime_service = self_clone_2.0.lock().ime_service.clone();
                    ime_service.update_keyboard_visibility_from_ime(&self_clone_2.0, false);
                }),
        );
    }

    /// Handles a TextFieldRequest, returning a FIDL error if one occurred when sending a reply.
    // TODO(lard): finish implementation
    fn handle_text_field_msg(&self, msg: txt::TextFieldRequest) -> Result<(), fidl::Error> {
        match msg {
            txt::TextFieldRequest::PointOffset { responder, .. } => {
                return responder.send(&mut txt::TextPoint { id: 0 }, txt::TextError::BadRequest);
            }
            txt::TextFieldRequest::Distance { responder, .. } => {
                return responder.send(0, txt::TextError::BadRequest);
            }
            txt::TextFieldRequest::Contents { responder, .. } => {
                return responder.send(
                    "",
                    &mut txt::TextPoint { id: 0 },
                    txt::TextError::BadRequest,
                );
            }
            txt::TextFieldRequest::CommitEdit { responder, .. } => {
                return responder.send(txt::TextError::BadRequest);
            }
            // other cases don't have a responder, so we can just ignore in this temporary code
            // instead of replying with an error.
            _ => {
                return Ok(());
            }
        }
    }

    /// Handles a request from the legancy IME API, an InputMethodEditorRequest.
    fn handle_ime_message(&self, msg: uii::InputMethodEditorRequest) {
        match msg {
            ImeReq::SetKeyboardType { keyboard_type, .. } => {
                let mut state = self.0.lock();
                state.keyboard_type = keyboard_type;
            }
            ImeReq::SetState { state, .. } => {
                self.set_state(state);
            }
            ImeReq::InjectInput { event, .. } => {
                self.inject_input(event);
            }
            ImeReq::Show { .. } => {
                // clone to ensure we only hold one lock at a time
                let ime_service = self.0.lock().ime_service.clone();
                ime_service.show_keyboard();
            }
            ImeReq::Hide { .. } => {
                // clone to ensure we only hold one lock at a time
                let ime_service = self.0.lock().ime_service.clone();
                ime_service.hide_keyboard();
            }
        }
    }

    fn set_state(&self, input_state: uii::TextInputState) {
        let mut state = self.0.lock();
        state.text_state = input_state;
        // the old C++ IME implementation didn't call did_update_state here, so this second argument is false.
        state.increment_revision(None, false);
    }

    pub fn inject_input(&self, event: uii::InputEvent) {
        let mut state = self.0.lock();
        let keyboard_event = match event {
            uii::InputEvent::Keyboard(e) => e,
            _ => return,
        };

        if keyboard_event.phase == uii::KeyboardEventPhase::Pressed
            || keyboard_event.phase == uii::KeyboardEventPhase::Repeat
        {
            if keyboard_event.code_point != 0 {
                state.type_keycode(keyboard_event.code_point);
                state.increment_revision(Some(keyboard_event), true)
            } else {
                match keyboard_event.hid_usage {
                    HID_USAGE_KEY_BACKSPACE => {
                        state.delete_backward();
                        state.increment_revision(Some(keyboard_event), true);
                    }
                    HID_USAGE_KEY_DELETE => {
                        state.delete_forward();
                        state.increment_revision(Some(keyboard_event), true);
                    }
                    HID_USAGE_KEY_LEFT => {
                        state.cursor_horizontal_move(keyboard_event.modifiers, false);
                        state.increment_revision(Some(keyboard_event), true);
                    }
                    HID_USAGE_KEY_RIGHT => {
                        state.cursor_horizontal_move(keyboard_event.modifiers, true);
                        state.increment_revision(Some(keyboard_event), true);
                    }
                    HID_USAGE_KEY_ENTER => {
                        state.client.on_action(state.action).unwrap_or_else(|e| {
                            fx_log_warn!("error sending action to ImeClient: {:?}", e)
                        });
                    }
                    _ => {
                        // Not an editing key, forward the event to clients.
                        state.increment_revision(Some(keyboard_event), true);
                    }
                }
            }
        }
    }
}

/// Horizontal motion type for the cursor.
enum HorizontalMotion {
    GraphemeLeft(GraphemeTraversal),
    GraphemeRight,
    WordLeft,
    WordRight,
}

/// How the cursor should traverse grapheme clusters.
enum GraphemeTraversal {
    /// Move by whole grapheme clusters at a time.
    ///
    /// This traversal mode should be used when using arrow keys, or when deleting forward (with the
    /// <kbd>Delete</kbd> key).
    WholeGrapheme,
    /// Generally move by whole grapheme clusters, but allow moving through individual combining
    /// characters, if present at the end of the grapheme cluster.
    ///
    /// This traversal mode should be used when deleting backward (<kbd>Backspace</kbd>), but not
    /// when deleting forward or using arrow keys.
    ///
    /// This ensures that when a user is typing text and composes a character out of individual
    /// combining diacritics, it should be possible to correct a mistake by pressing
    /// <kbd>Backspace</kbd>. If we were to allow _moving the cursor_ left and right through
    /// diacritics, that would only cause user confusion, as the blinking caret would not move
    /// visibly while within a single grapheme cluster.
    CombiningCharacters,
}

impl ImeState {
    /// Any time the state is updated, this method is called, which allows ImeState to inform any
    /// listening clients (either TextField or InputMethodEditorClientProxy) that state has updated.
    /// If InputMethodEditorClient caused the update with SetState, set call_did_update_state so that
    /// we don't send its own edit back to it. Otherwise, set to true.
    pub fn increment_revision(
        &mut self,
        e: Option<uii::KeyboardEvent>,
        call_did_update_state: bool,
    ) {
        self.revision += 1;
        self.text_points = HashMap::new();
        let mut state = self.as_text_field_state();
        if let Some(input_method) = &self.input_method {
            if let Err(e) = input_method.send_on_update(&mut state) {
                fx_log_err!("error when sending update to TextField listener: {}", e);
            }
        }

        if call_did_update_state {
            if let Some(ev) = e {
                self.client
                    .did_update_state(
                        &mut self.text_state,
                        Some(OutOfLine(&mut uii::InputEvent::Keyboard(ev))),
                    )
                    .unwrap_or_else(|e| {
                        fx_log_warn!("error sending state update to ImeClient: {:?}", e)
                    });
            } else {
                self.client.did_update_state(&mut self.text_state, None).unwrap_or_else(|e| {
                    fx_log_warn!("error sending state update to ImeClient: {:?}", e)
                });
            }
        }
    }

    /// Converts the current self.text_state (the IME API v1 representation of the text field's state)
    /// into the v2 representation txt::TextFieldState.
    fn as_text_field_state(&mut self) -> txt::TextFieldState {
        let anchor_first = self.text_state.selection.base < self.text_state.selection.extent;
        txt::TextFieldState {
            document: txt::TextRange {
                start: self.new_point(0),
                end: self.new_point(self.text_state.text.len()),
            },
            selection: Some(Box::new(txt::TextSelection {
                range: txt::TextRange {
                    start: self.new_point(if anchor_first {
                        self.text_state.selection.base as usize
                    } else {
                        self.text_state.selection.extent as usize
                    }),
                    end: self.new_point(if anchor_first {
                        self.text_state.selection.extent as usize
                    } else {
                        self.text_state.selection.base as usize
                    }),
                },
                anchor: if anchor_first {
                    txt::TextSelectionAnchor::AnchoredAtStart
                } else {
                    txt::TextSelectionAnchor::AnchoredAtEnd
                },
                affinity: txt::TextAffinity::Upstream,
            })),
            // TODO(lard): these three regions should be correctly populated from text_state.
            composition: None,
            composition_highlight: None,
            dead_key_highlight: None,
            revision: self.revision,
        }
    }

    /// Creates a new TextPoint corresponding to the byte index `index`.
    fn new_point(&mut self, index: usize) -> txt::TextPoint {
        let id = self.next_text_point_id;
        self.next_text_point_id += 1;
        self.text_points.insert(id, index);
        txt::TextPoint { id }
    }

    // gets start and len, and sets base/extent to start of string if don't exist
    pub fn selection(&mut self) -> Range<usize> {
        let s = &mut self.text_state.selection;
        s.base = s.base.max(0).min(self.text_state.text.len() as i64);
        s.extent = s.extent.max(0).min(self.text_state.text.len() as i64);
        let start = s.base.min(s.extent) as usize;
        let end = s.base.max(s.extent) as usize;
        (start..end)
    }

    pub fn type_keycode(&mut self, code_point: u32) {
        self.text_state.revision += 1;

        let replacement = match char::from_u32(code_point) {
            Some(v) => v.to_string(),
            None => return,
        };

        let selection = self.selection();
        self.text_state.text.replace_range(selection.clone(), &replacement);

        self.text_state.selection.base = selection.start as i64 + replacement.len() as i64;
        self.text_state.selection.extent = self.text_state.selection.base;
    }

    /// Calculates an adjacent cursor position to left or right of the current position.
    ///
    /// * `start`: Starting position in the string, as a byte offset.
    /// * `motion`: Whether to go right or left, and whether to allow entering grapheme clusters.
    fn adjacent_cursor_position(&self, start: usize, motion: HorizontalMotion) -> usize {
        match motion {
            HorizontalMotion::GraphemeRight => self.adjacent_cursor_position_grapheme_right(start),
            HorizontalMotion::GraphemeLeft(traversal) => {
                self.adjacent_cursor_position_grapheme_left(start, traversal)
            }
            HorizontalMotion::WordLeft => self.adjacent_cursor_position_word_left(start),
            HorizontalMotion::WordRight => self.adjacent_cursor_position_word_right(start),
        }
    }

    fn adjacent_cursor_position_word_left(&self, start: usize) -> usize {
        if start == 0 {
            return 0;
        }
        let text = &self.text_state.text[0..start];
        // Find the next word to the left.
        let word = match UnicodeSegmentation::unicode_words(text).rev().next() {
            Some(word) => word,
            // No words - go to the string start.
            None => return 0,
        };
        // Find start of the next word.
        if let Some((pos, _)) = UnicodeSegmentation::split_word_bound_indices(text)
            .rev()
            .find(|(_, next_word)| next_word == &word)
        {
            pos
        } else {
            0
        }
    }

    fn adjacent_cursor_position_word_right(&self, start: usize) -> usize {
        let text = &self.text_state.text[start..];
        let text_length = text.len();
        if text_length == 0 {
            return start;
        }
        let mut words_iter = UnicodeSegmentation::unicode_words(text);
        // Find the next word to the right.
        let word = match words_iter.next() {
            Some(word) => word,
            // No words - go the end of the string.
            None => return start + text_length,
        };
        let mut word_bound_indices = UnicodeSegmentation::split_word_bound_indices(text);
        // Skip over boundaries until a next word is found.
        let word_bound = word_bound_indices.find(|(_, next_word)| next_word == &word);

        // Return start of the next boundary after the word, if there is one.
        if let Some((next_boundary_pos, _)) = word_bound_indices.next() {
            start + next_boundary_pos
        } else if let Some((pos, next_word)) = word_bound {
            // Last word - go to end of the word.
            start + pos + next_word.len()
        } else {
            // No more words - go to the end of the line.
            start + text_length
        }
    }

    fn get_grapheme_boundary(&self, start: usize, next: bool) -> Option<usize> {
        let text_length = self.text_state.text.len();
        let mut cursor = GraphemeCursor::new(start, text_length, true);
        let result = if next {
            cursor.next_boundary(&self.text_state.text, 0)
        } else {
            cursor.prev_boundary(&self.text_state.text, 0)
        };
        result.unwrap_or(None)
    }

    fn adjacent_cursor_position_grapheme_right(&self, start: usize) -> usize {
        self.get_grapheme_boundary(start, true).unwrap_or(self.text_state.text.len())
    }

    fn adjacent_cursor_position_grapheme_left(
        &self,
        start: usize,
        traversal: GraphemeTraversal,
    ) -> usize {
        let prev_boundary = self.get_grapheme_boundary(start, false);
        if let Some(offset) = prev_boundary {
            if let GraphemeTraversal::CombiningCharacters = traversal {
                let grapheme_str = &self.text_state.text[offset..start];
                let last_char_str = match grapheme_str.char_indices().last() {
                    Some((last_char_offset, _c)) => Some(&grapheme_str[last_char_offset..]),
                    None => None,
                };
                if let Some(last_char_str) = last_char_str {
                    lazy_static! {
                        /// A regex that matches combining characters, e.g. accents and other
                        /// diacritics. Rust does not provide a way to check the Unicode categories
                        /// of `char`s directly, so this is the simplest workaround for now.
                        static ref COMBINING_REGEX: Regex = Regex::new(r"\p{M}$").unwrap();
                    }
                    if COMBINING_REGEX.is_match(last_char_str) {
                        return start - last_char_str.len();
                    }
                }
            }
            offset
        } else {
            // Can't go left from the beginning of the string.
            0
        }
    }

    pub fn delete_backward(&mut self) {
        self.text_state.revision += 1;

        // set base and extent to 0 if either is -1, to ensure there is a selection/cursor
        self.selection();

        if self.text_state.selection.base == self.text_state.selection.extent {
            // Select one grapheme or character to the left, so that it can be uniformly handled by
            // the selection-deletion code below.
            self.text_state.selection.base = self.adjacent_cursor_position(
                self.text_state.selection.base as usize,
                HorizontalMotion::GraphemeLeft(GraphemeTraversal::CombiningCharacters),
            ) as i64;
        }
        self.delete_selection();
    }

    pub fn delete_forward(&mut self) {
        self.text_state.revision += 1;

        // Ensure valid selection/cursor.
        self.selection();

        if self.text_state.selection.base == self.text_state.selection.extent {
            // Select one grapheme to the right so that it can be handled by the selection-deletion
            // code below.
            self.text_state.selection.extent = self.adjacent_cursor_position(
                self.text_state.selection.base as usize,
                HorizontalMotion::GraphemeRight,
            ) as i64;
        }
        self.delete_selection();
    }

    /// Deletes the selected text if the selection isn't empty.
    /// Does not increment revision number. Should only be called from methods that do.
    fn delete_selection(&mut self) {
        // Delete the current selection.
        let selection = self.selection();
        if selection.start != selection.end {
            self.text_state.text.replace_range(selection.clone(), "");
            self.text_state.selection.extent = selection.start as i64;
            self.text_state.selection.base = self.text_state.selection.extent;
        }
    }

    pub fn cursor_horizontal_move(&mut self, modifiers: u32, go_right: bool) {
        self.text_state.revision += 1;

        let shift_pressed = modifiers & uii::MODIFIER_SHIFT != 0;
        let ctrl_pressed = modifiers & uii::MODIFIER_CONTROL != 0;
        let selection = self.selection();
        let text_is_selected = selection.start != selection.end;
        let mut new_position = self.text_state.selection.extent;

        if !shift_pressed && text_is_selected {
            // canceling selection, new position based on start/end of selection
            if go_right {
                new_position = selection.end as i64;
            } else {
                new_position = selection.start as i64;
            }
            if ctrl_pressed {
                new_position = self.adjacent_cursor_position(
                    new_position as usize,
                    if go_right { HorizontalMotion::WordRight } else { HorizontalMotion::WordLeft },
                ) as i64;
            }
        } else {
            // new position based previous value of extent
            new_position = self.adjacent_cursor_position(
                new_position as usize,
                match (go_right, ctrl_pressed) {
                    (true, true) => HorizontalMotion::WordRight,
                    (false, true) => HorizontalMotion::WordLeft,
                    (true, false) => HorizontalMotion::GraphemeRight,
                    (false, false) => {
                        HorizontalMotion::GraphemeLeft(GraphemeTraversal::WholeGrapheme)
                    }
                },
            ) as i64;
        }

        self.text_state.selection.extent = new_position;
        if !shift_pressed {
            self.text_state.selection.base = new_position;
        }
        self.text_state.selection.affinity = uii::TextAffinity::Downstream;
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::test_helpers::{clone_state, default_state};
    use fidl;
    use fuchsia_zircon as zx;
    use std::sync::mpsc::{channel, Receiver, Sender};

    fn set_up(
        text: &str,
        base: i64,
        extent: i64,
    ) -> (Ime, Receiver<uii::TextInputState>, Receiver<uii::InputMethodAction>) {
        let (client, statechan, actionchan) = MockImeClient::new();
        let mut state = default_state();
        state.text = text.to_string();
        state.selection.base = base;
        state.selection.extent = extent;
        let ime = Ime::new(
            uii::KeyboardType::Text,
            uii::InputMethodAction::Search,
            state,
            client,
            ImeService::new(),
        );
        (ime, statechan, actionchan)
    }

    fn simulate_keypress<K: Into<u32> + Copy>(
        ime: &mut Ime,
        key: K,
        hid_key: bool,
        modifiers: u32,
    ) {
        let hid_usage = if hid_key { key.into() } else { 0 };
        let code_point = if hid_key { 0 } else { key.into() };
        ime.inject_input(uii::InputEvent::Keyboard(uii::KeyboardEvent {
            event_time: 0,
            device_id: 0,
            phase: uii::KeyboardEventPhase::Pressed,
            hid_usage,
            code_point,
            modifiers,
        }));
        ime.inject_input(uii::InputEvent::Keyboard(uii::KeyboardEvent {
            event_time: 0,
            device_id: 0,
            phase: uii::KeyboardEventPhase::Released,
            hid_usage,
            code_point,
            modifiers,
        }));
    }

    struct MockImeClient {
        pub state: Mutex<Sender<uii::TextInputState>>,
        pub action: Mutex<Sender<uii::InputMethodAction>>,
    }
    impl MockImeClient {
        fn new() -> (MockImeClient, Receiver<uii::TextInputState>, Receiver<uii::InputMethodAction>)
        {
            let (s_send, s_rec) = channel();
            let (a_send, a_rec) = channel();
            let client = MockImeClient { state: Mutex::new(s_send), action: Mutex::new(a_send) };
            (client, s_rec, a_rec)
        }
    }
    impl uii::InputMethodEditorClientProxyInterface for MockImeClient {
        fn did_update_state(
            &self,
            state: &mut uii::TextInputState,
            mut _event: Option<fidl::encoding::OutOfLine<uii::InputEvent>>,
        ) -> Result<(), fidl::Error> {
            let state2 = clone_state(state);
            self.state
                .lock()
                .send(state2)
                .map_err(|_| fidl::Error::ClientWrite(zx::Status::PEER_CLOSED))
        }
        fn on_action(&self, action: uii::InputMethodAction) -> Result<(), fidl::Error> {
            self.action
                .lock()
                .send(action)
                .map_err(|_| fidl::Error::ClientWrite(zx::Status::PEER_CLOSED))
        }
    }

    #[test]
    fn test_mock_ime_channels() {
        let (client, statechan, actionchan) = MockImeClient::new();
        let mut ime = Ime::new(
            uii::KeyboardType::Text,
            uii::InputMethodAction::Search,
            default_state(),
            client,
            ImeService::new(),
        );
        assert_eq!(true, statechan.try_recv().is_err());
        assert_eq!(true, actionchan.try_recv().is_err());
        simulate_keypress(&mut ime, 'a', false, uii::MODIFIER_NONE);
        assert_eq!(false, statechan.try_recv().is_err());
        assert_eq!(true, actionchan.try_recv().is_err());
    }

    #[test]
    fn test_delete_backward_empty_string() {
        let (mut ime, statechan, _actionchan) = set_up("", -1, -1);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);

        // a second delete still does nothing, but increments revision
        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_delete_forward_empty_string() {
        let (mut ime, statechan, _actionchan) = set_up("", -1, -1);

        simulate_keypress(&mut ime, HID_USAGE_KEY_DELETE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);

        // a second delete still does nothing, but increments revision
        simulate_keypress(&mut ime, HID_USAGE_KEY_DELETE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_delete_backward_beginning_string() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 0, 0);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghi", state.text);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_delete_forward_beginning_string() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 0, 0);

        simulate_keypress(&mut ime, HID_USAGE_KEY_DELETE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("bcdefghi", state.text);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_delete_backward_first_char_selected() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 0, 1);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("bcdefghi", state.text);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_delete_forward_last_char_selected() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 8, 9);

        simulate_keypress(&mut ime, HID_USAGE_KEY_DELETE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefgh", state.text);
        assert_eq!(8, state.selection.base);
        assert_eq!(8, state.selection.extent);
    }

    #[test]
    fn test_delete_backward_end_string() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 9, 9);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefgh", state.text);
        assert_eq!(8, state.selection.base);
        assert_eq!(8, state.selection.extent);
    }

    #[test]
    fn test_delete_forward_end_string() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 9, 9);

        simulate_keypress(&mut ime, HID_USAGE_KEY_DELETE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghi", state.text);
        assert_eq!(9, state.selection.base);
        assert_eq!(9, state.selection.extent);
    }

    #[test]
    fn test_delete_backward_combining_diacritic() {
        // U+0301: combining acute accent. 2 bytes.
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi\u{0301}", 11, 11);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghi", state.text);
        assert_eq!(9, state.selection.base);
        assert_eq!(9, state.selection.extent);
    }

    #[test]
    fn test_delete_forward_combining_diacritic() {
        // U+0301: combining acute accent. 2 bytes.
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi\u{0301}jkl", 8, 8);

        simulate_keypress(&mut ime, HID_USAGE_KEY_DELETE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghjkl", state.text);
        assert_eq!(8, state.selection.base);
        assert_eq!(8, state.selection.extent);
    }

    #[test]
    fn test_delete_backward_emoji() {
        // Emoji with a color modifier.
        let text = "abcdefghi👦🏻";
        let len = text.len() as i64;
        let (mut ime, statechan, _actionchan) = set_up(text, len, len);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghi", state.text);
        assert_eq!(9, state.selection.base);
        assert_eq!(9, state.selection.extent);
    }

    #[test]
    fn test_delete_forward_emoji() {
        // Emoji with a color modifier.
        let text = "abcdefghi👦🏻";
        let (mut ime, statechan, _actionchan) = set_up(text, 9, 9);

        simulate_keypress(&mut ime, HID_USAGE_KEY_DELETE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghi", state.text);
        assert_eq!(9, state.selection.base);
        assert_eq!(9, state.selection.extent);
    }

    /// Flags are more complicated because they consist of two REGIONAL INDICATOR SYMBOL LETTERs.
    #[test]
    fn test_delete_backward_flag() {
        // French flag
        let text = "abcdefghi🇫🇷";
        let len = text.len() as i64;
        let (mut ime, statechan, _actionchan) = set_up(text, len, len);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghi", state.text);
        assert_eq!(9, state.selection.base);
        assert_eq!(9, state.selection.extent);
    }

    #[test]
    fn test_delete_forward_flag() {
        // French flag
        let text = "abcdefghi🇫🇷";
        let (mut ime, statechan, _actionchan) = set_up(text, 9, 9);

        simulate_keypress(&mut ime, HID_USAGE_KEY_DELETE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghi", state.text);
        assert_eq!(9, state.selection.base);
        assert_eq!(9, state.selection.extent);
    }

    #[test]
    fn test_delete_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 3, 6);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcghi", state.text);
        assert_eq!(3, state.selection.base);
        assert_eq!(3, state.selection.extent);
    }

    #[test]
    fn test_delete_selection_inverted() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 6, 3);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcghi", state.text);
        assert_eq!(3, state.selection.base);
        assert_eq!(3, state.selection.extent);
    }

    #[test]
    fn test_delete_no_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", -1, -1);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefghi", state.text);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_delete_with_zero_width_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 3, 3);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abdefghi", state.text);
        assert_eq!(2, state.selection.base);
        assert_eq!(2, state.selection.extent);
    }

    #[test]
    fn test_delete_with_zero_width_selection_at_end() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 9, 9);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefgh", state.text);
        assert_eq!(8, state.selection.base);
        assert_eq!(8, state.selection.extent);
    }

    #[test]
    fn test_delete_selection_out_of_bounds() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 20, 24);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abcdefgh", state.text);
        assert_eq!(8, state.selection.base);
        assert_eq!(8, state.selection.extent);
    }

    #[test]
    fn test_cursor_left_on_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 1, 5);

        // right with shift
        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_SHIFT);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(1, state.selection.base);
        assert_eq!(6, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!(1, state.selection.base);
        assert_eq!(1, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(4, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(5, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_cursor_left_on_inverted_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 6, 3);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(3, state.selection.base);
        assert_eq!(3, state.selection.extent);
    }

    #[test]
    fn test_cursor_right_on_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdefghi", 3, 9);

        // left with shift
        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_SHIFT);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(3, state.selection.base);
        assert_eq!(8, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!(8, state.selection.base);
        assert_eq!(8, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(4, state.revision);
        assert_eq!(9, state.selection.base);
        assert_eq!(9, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(5, state.revision);
        assert_eq!(9, state.selection.base);
        assert_eq!(9, state.selection.extent);
    }

    #[test]
    fn test_cursor_word_left_no_words() {
        let (mut ime, statechan, _actionchan) = set_up("¿ - _ - ?", 5, 5);

        // left with control
        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_cursor_word_left() {
        let (mut ime, statechan, _actionchan) = set_up("4.2 . foobar", 7, 7);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(6, state.selection.base);
        assert_eq!(6, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_cursor_word_right_no_words() {
        let (mut ime, statechan, _actionchan) = set_up("¿ - _ - ?", 5, 5);

        // right with control
        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(10, state.selection.base);
        assert_eq!(10, state.selection.extent);
    }

    #[test]
    fn test_cursor_word_right() {
        let (mut ime, statechan, _actionchan) = set_up("4.2 . foobar", 1, 1);

        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(3, state.selection.base);
        assert_eq!(3, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!(12, state.selection.base);
        assert_eq!(12, state.selection.extent);

        // Try to navigate off text limits.
        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(4, state.revision);
        assert_eq!(12, state.selection.base);
        assert_eq!(12, state.selection.extent);
    }

    #[test]
    fn test_cursor_word_off_limits() {
        let (mut ime, statechan, _actionchan) = set_up("word", 1, 1);

        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(4, state.selection.base);
        assert_eq!(4, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!(4, state.selection.base);
        assert_eq!(4, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(4, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(5, state.revision);
        assert_eq!(0, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_cursor_word() {
        let (mut ime, statechan, _actionchan) = set_up("a.c   2.2 ¿? x yz", 8, 8);

        simulate_keypress(
            &mut ime,
            HID_USAGE_KEY_RIGHT,
            true,
            uii::MODIFIER_CONTROL | uii::MODIFIER_SHIFT,
        );
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!(8, state.selection.base);
        assert_eq!(9, state.selection.extent);

        simulate_keypress(
            &mut ime,
            HID_USAGE_KEY_RIGHT,
            true,
            uii::MODIFIER_CONTROL | uii::MODIFIER_SHIFT,
        );
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!(8, state.selection.base);
        assert_eq!(15, state.selection.extent);

        simulate_keypress(&mut ime, HID_USAGE_KEY_LEFT, true, uii::MODIFIER_CONTROL);
        let state = statechan.try_recv().unwrap();
        assert_eq!(4, state.revision);
        assert_eq!(6, state.selection.base);
        assert_eq!(6, state.selection.extent);

        simulate_keypress(
            &mut ime,
            HID_USAGE_KEY_LEFT,
            true,
            uii::MODIFIER_CONTROL | uii::MODIFIER_SHIFT,
        );
        let state = statechan.try_recv().unwrap();
        assert_eq!(5, state.revision);
        assert_eq!(6, state.selection.base);
        assert_eq!(0, state.selection.extent);
    }

    #[test]
    fn test_type_empty_string() {
        let (mut ime, statechan, _actionchan) = set_up("", 0, 0);

        simulate_keypress(&mut ime, 'a', false, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("a", state.text);
        assert_eq!(1, state.selection.base);
        assert_eq!(1, state.selection.extent);

        simulate_keypress(&mut ime, 'b', false, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!("ab", state.text);
        assert_eq!(2, state.selection.base);
        assert_eq!(2, state.selection.extent);
    }

    #[test]
    fn test_type_at_beginning() {
        let (mut ime, statechan, _actionchan) = set_up("cde", 0, 0);

        simulate_keypress(&mut ime, 'a', false, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("acde", state.text);
        assert_eq!(1, state.selection.base);
        assert_eq!(1, state.selection.extent);

        simulate_keypress(&mut ime, 'b', false, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!("abcde", state.text);
        assert_eq!(2, state.selection.base);
        assert_eq!(2, state.selection.extent);
    }

    #[test]
    fn test_type_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdef", 2, 5);

        simulate_keypress(&mut ime, 'x', false, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abxf", state.text);
        assert_eq!(3, state.selection.base);
        assert_eq!(3, state.selection.extent);
    }

    #[test]
    fn test_type_inverted_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdef", 5, 2);

        simulate_keypress(&mut ime, 'x', false, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("abxf", state.text);
        assert_eq!(3, state.selection.base);
        assert_eq!(3, state.selection.extent);
    }

    #[test]
    fn test_type_invalid_selection() {
        let (mut ime, statechan, _actionchan) = set_up("abcdef", -10, 1);

        simulate_keypress(&mut ime, 'x', false, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("xbcdef", state.text);
        assert_eq!(1, state.selection.base);
        assert_eq!(1, state.selection.extent);
    }

    #[test]
    fn test_set_state() {
        let (mut ime, statechan, _actionchan) = set_up("abcdef", 1, 1);

        let mut override_state = default_state();
        override_state.text = "meow?".to_string();
        override_state.selection.base = 4;
        override_state.selection.extent = 5;
        ime.set_state(override_state);
        simulate_keypress(&mut ime, '!', false, uii::MODIFIER_NONE);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("meow!", state.text);
        assert_eq!(5, state.selection.base);
        assert_eq!(5, state.selection.extent);
    }

    #[test]
    fn test_action() {
        let (mut ime, statechan, actionchan) = set_up("abcdef", 1, 1);

        simulate_keypress(&mut ime, HID_USAGE_KEY_ENTER, true, uii::MODIFIER_NONE);
        assert!(statechan.try_recv().is_err()); // assert did not update state
        assert!(actionchan.try_recv().is_ok()); // assert DID send action
    }

    #[test]
    fn test_unicode_selection() {
        let (mut ime, statechan, _actionchan) = set_up("m😸eow", 1, 1);

        simulate_keypress(&mut ime, HID_USAGE_KEY_RIGHT, true, uii::MODIFIER_SHIFT);
        assert!(statechan.try_recv().is_ok());

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_SHIFT);
        let state = statechan.try_recv().unwrap();
        assert_eq!(3, state.revision);
        assert_eq!("meow", state.text);
        assert_eq!(1, state.selection.base);
        assert_eq!(1, state.selection.extent);
    }

    #[test]
    fn test_unicode_backspace() {
        let base: i64 = "m😸".len() as i64;
        let (mut ime, statechan, _actionchan) = set_up("m😸eow", base, base);

        simulate_keypress(&mut ime, HID_USAGE_KEY_BACKSPACE, true, uii::MODIFIER_SHIFT);
        let state = statechan.try_recv().unwrap();
        assert_eq!(2, state.revision);
        assert_eq!("meow", state.text);
        assert_eq!(1, state.selection.base);
        assert_eq!(1, state.selection.extent);
    }
}
