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

#![cfg(test)]

use {
    anyhow::{Context as _, Error},
    fidl_fuchsia_input as input, fidl_fuchsia_ui_input as ui_input,
    fuchsia_async::{self as fasync},
    fuchsia_component::client::connect_to_protocol,
};

use test_helpers::{
    bind_editor, default_state, get_action, get_state_update, measure_utf16, setup_ime,
    simulate_ime_keypress, simulate_ime_keypress_with_held_keys,
};

#[fasync::run_singlethreaded(test)]
async fn test_delete_backward_empty_string() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "", -1, -1).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    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_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_forward_empty_string() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "", -1, -1).await?;

    simulate_ime_keypress(&ime, input::Key::Delete).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    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_ime_keypress(&ime, input::Key::Delete).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_backward_beginning_string() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 0, 0).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_forward_beginning_string() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 0, 0).await?;

    simulate_ime_keypress(&ime, input::Key::Delete).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("bcdefghi", state.text);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_backward_first_char_selected() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 0, 1).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("bcdefghi", state.text);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_forward_last_char_selected() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 8, 9).await?;

    simulate_ime_keypress(&ime, input::Key::Delete).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefgh", state.text);
    assert_eq!(8, state.selection.base);
    assert_eq!(8, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_backward_end_string() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 9, 9).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefgh", state.text);
    assert_eq!(8, state.selection.base);
    assert_eq!(8, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_forward_end_string() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 9, 9).await?;

    simulate_ime_keypress(&ime, input::Key::Delete).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(9, state.selection.base);
    assert_eq!(9, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_backward_combining_diacritic() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    // U+0301: combining acute accent. 2 bytes.
    let text = "abcdefghi\u{0301}";
    let len = measure_utf16(text) as i64;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, text, len, len).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(9, state.selection.base);
    assert_eq!(9, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_forward_combining_diacritic() -> Result<(), Error> {
    // U+0301: combining acute accent. 2 bytes.
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi\u{0301}jkl", 8, 8).await?;

    simulate_ime_keypress(&ime, input::Key::Delete).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghjkl", state.text);
    assert_eq!(8, state.selection.base);
    assert_eq!(8, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_backward_emoji() -> Result<(), Error> {
    // Emoji with a color modifier.
    let text = "abcdefghi👦🏻";
    let len = measure_utf16(text) as i64;
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, text, len, len).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(9, state.selection.base);
    assert_eq!(9, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_forward_emoji() -> Result<(), Error> {
    // Emoji with a color modifier.
    let text = "abcdefghi👦🏻";
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, text, 9, 9).await?;

    simulate_ime_keypress(&ime, input::Key::Delete).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(9, state.selection.base);
    assert_eq!(9, state.selection.extent);

    Ok(())
}

/// Flags are more complicated because they consist of two REGIONAL INDICATOR SYMBOL LETTERs.
#[fasync::run_singlethreaded(test)]
async fn test_delete_backward_flag() -> Result<(), Error> {
    // French flag
    let text = "abcdefghi🇫🇷";
    let len = measure_utf16(text) as i64;
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, text, len, len).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(9, state.selection.base);
    assert_eq!(9, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_forward_flag() -> Result<(), Error> {
    // French flag
    let text = "abcdefghi🇫🇷";
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, text, 9, 9).await?;

    simulate_ime_keypress(&ime, input::Key::Delete).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(9, state.selection.base);
    assert_eq!(9, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 3, 6).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcghi", state.text);
    assert_eq!(3, state.selection.base);
    assert_eq!(3, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_selection_inverted() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 6, 3).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcghi", state.text);
    assert_eq!(3, state.selection.base);
    assert_eq!(3, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_no_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", -1, -1).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_with_zero_width_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 3, 3).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abdefghi", state.text);
    assert_eq!(2, state.selection.base);
    assert_eq!(2, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_with_zero_width_selection_at_end() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 9, 9).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefgh", state.text);
    assert_eq!(8, state.selection.base);
    assert_eq!(8, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_delete_selection_out_of_bounds() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 20, 24).await?;

    simulate_ime_keypress(&ime, input::Key::Backspace).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abcdefghi", state.text);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_left_on_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 1, 5).await?;

    // right with shift
    simulate_ime_keypress_with_held_keys(&ime, input::Key::Right, vec![input::Key::LeftShift])
        .await;

    // Skip the update for the shift key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(1, state.selection.base);
    assert_eq!(6, state.selection.extent);

    simulate_ime_keypress(&ime, input::Key::Left).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!(1, state.selection.base);
    assert_eq!(1, state.selection.extent);

    simulate_ime_keypress(&ime, input::Key::Left).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(4, state.revision);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    simulate_ime_keypress(&ime, input::Key::Left).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(5, state.revision);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_left_on_inverted_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 6, 3).await?;

    simulate_ime_keypress(&ime, input::Key::Left).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(3, state.selection.base);
    assert_eq!(3, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_right_on_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdefghi", 3, 9).await?;

    // left with shift
    simulate_ime_keypress_with_held_keys(&ime, input::Key::Left, vec![input::Key::LeftShift]).await;

    // Skip the update for the shift key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(3, state.selection.base);
    assert_eq!(8, state.selection.extent);

    simulate_ime_keypress(&ime, input::Key::Right).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!(8, state.selection.base);
    assert_eq!(8, state.selection.extent);

    simulate_ime_keypress(&ime, input::Key::Right).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(4, state.revision);
    assert_eq!(9, state.selection.base);
    assert_eq!(9, state.selection.extent);

    simulate_ime_keypress(&ime, input::Key::Right).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(5, state.revision);
    assert_eq!(9, state.selection.base);
    assert_eq!(9, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_word_left_no_words() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "¿ - _ - ?", 5, 5).await?;

    // left with control
    simulate_ime_keypress_with_held_keys(&ime, input::Key::Left, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_word_left() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "4.2 . foobar", 7, 7).await?;

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Left, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(6, state.selection.base);
    assert_eq!(6, state.selection.extent);

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Left, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_word_right_no_words() -> Result<(), Error> {
    let text = "¿ - _ - ?";
    let text_len = measure_utf16(text) as i64;
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, text, 5, 5).await?;

    // right with control
    simulate_ime_keypress_with_held_keys(&ime, input::Key::Right, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(text_len, state.selection.base);
    assert_eq!(text_len, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_word_right() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "4.2 . foobar", 1, 1).await?;

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Right, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(3, state.selection.base);
    assert_eq!(3, state.selection.extent);

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Right, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!(12, state.selection.base);
    assert_eq!(12, state.selection.extent);

    // Try to navigate off text limits.
    simulate_ime_keypress_with_held_keys(&ime, input::Key::Right, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(4, state.revision);
    assert_eq!(12, state.selection.base);
    assert_eq!(12, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_word_off_limits() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "word", 1, 1).await?;

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Right, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(4, state.selection.base);
    assert_eq!(4, state.selection.extent);

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Right, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!(4, state.selection.base);
    assert_eq!(4, state.selection.extent);

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Left, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(4, state.revision);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Left, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(5, state.revision);
    assert_eq!(0, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_cursor_word() -> Result<(), Error> {
    let start_idx = measure_utf16("a.c   2.") as i64;
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "a.c   2.2 ¿? x yz", start_idx, start_idx).await?;

    simulate_ime_keypress_with_held_keys(
        &ime,
        input::Key::Right,
        vec![input::Key::LeftShift, input::Key::LeftCtrl],
    )
    .await;

    // Skip the update for the shift and the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!(start_idx, state.selection.base);
    assert_eq!(measure_utf16("a.c   2.2") as i64, state.selection.extent);

    simulate_ime_keypress_with_held_keys(
        &ime,
        input::Key::Right,
        vec![input::Key::LeftShift, input::Key::LeftCtrl],
    )
    .await;

    // Skip the update for the shift and the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!(start_idx, state.selection.base);
    assert_eq!(measure_utf16("a.c   2.2 ¿? x") as i64, state.selection.extent);

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Left, vec![input::Key::LeftCtrl]).await;

    // Skip the update for the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(4, state.revision);
    assert_eq!(measure_utf16("a.c   ") as i64, state.selection.base);
    assert_eq!(measure_utf16("a.c   ") as i64, state.selection.extent);

    simulate_ime_keypress_with_held_keys(
        &ime,
        input::Key::Left,
        vec![input::Key::LeftShift, input::Key::LeftCtrl],
    )
    .await;

    // Skip the update for the shift and the ctrl key stroke.
    get_state_update(&mut editor_stream).await?;
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(5, state.revision);
    assert_eq!(measure_utf16("a.c   ") as i64, state.selection.base);
    assert_eq!(0, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_type_empty_string() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "", 0, 0).await?;

    simulate_ime_keypress(&ime, input::Key::A).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("a", state.text);
    assert_eq!(1, state.selection.base);
    assert_eq!(1, state.selection.extent);

    simulate_ime_keypress(&ime, input::Key::B).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!("ab", state.text);
    assert_eq!(2, state.selection.base);
    assert_eq!(2, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_type_at_beginning() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "cde", 0, 0).await?;

    simulate_ime_keypress(&ime, input::Key::A).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("acde", state.text);
    assert_eq!(1, state.selection.base);
    assert_eq!(1, state.selection.extent);

    simulate_ime_keypress(&ime, input::Key::B).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!("abcde", state.text);
    assert_eq!(2, state.selection.base);
    assert_eq!(2, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_type_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdef", 2, 5).await?;

    simulate_ime_keypress(&ime, input::Key::X).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abxf", state.text);
    assert_eq!(3, state.selection.base);
    assert_eq!(3, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_type_inverted_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdef", 5, 2).await?;

    simulate_ime_keypress(&ime, input::Key::X).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("abxf", state.text);
    assert_eq!(3, state.selection.base);
    assert_eq!(3, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_type_invalid_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdef", -10, 1).await?;

    simulate_ime_keypress(&ime, input::Key::X).await;
    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("xbcdef", state.text);
    assert_eq!(1, state.selection.base);
    assert_eq!(1, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_set_state() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdef", 1, 1).await?;

    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_ime_keypress_with_held_keys(&ime, input::Key::Key1, vec![input::Key::LeftShift]).await;

    // Skip the update for the shift key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("meow!", state.text);
    assert_eq!(5, state.selection.base);
    assert_eq!(5, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_action() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "abcdef", 1, 1).await?;

    simulate_ime_keypress(&ime, input::Key::Enter).await;
    // assert DID send action
    assert!(get_action(&mut editor_stream).await.is_ok());

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_unicode_selection() -> Result<(), Error> {
    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "m😸eow", 1, 1).await?;

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Right, vec![input::Key::LeftShift])
        .await;

    // Skip the update for the shift key stroke.
    get_state_update(&mut editor_stream).await?;

    let (_state, _event) = get_state_update(&mut editor_stream).await?;

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Backspace, vec![input::Key::LeftShift])
        .await;

    // Skip the update for the shift key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(3, state.revision);
    assert_eq!("meow", state.text);
    assert_eq!(1, state.selection.base);
    assert_eq!(1, state.selection.extent);

    Ok(())
}

#[fasync::run_singlethreaded(test)]
async fn test_unicode_backspace() -> Result<(), Error> {
    let base: i64 = measure_utf16("m😸") as i64;

    let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
        .context("Failed to connect to ImeService")?;

    let (ime, mut editor_stream) = bind_editor(&ime_service)?;
    setup_ime(&ime, "m😸eow", base, base).await?;

    simulate_ime_keypress_with_held_keys(&ime, input::Key::Backspace, vec![input::Key::LeftShift])
        .await;

    // Skip the update for the shift key stroke.
    get_state_update(&mut editor_stream).await?;

    let (state, _event) = get_state_update(&mut editor_stream).await?;
    assert_eq!(2, state.revision);
    assert_eq!("meow", state.text);
    assert_eq!(1, state.selection.base);
    assert_eq!(1, state.selection.extent);

    Ok(())
}
