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

use async_trait::async_trait;
use {
    anyhow::{format_err, Result},
    fidl_fuchsia_input as input, fidl_fuchsia_ui_input as ui_input,
    fidl_fuchsia_ui_input3 as ui_input3, fuchsia_zircon as zx,
    futures::{
        stream::{self, StreamExt, TryStreamExt},
        FutureExt,
    },
};

pub fn default_state() -> ui_input::TextInputState {
    ui_input::TextInputState {
        revision: 1,
        text: "".to_string(),
        selection: ui_input::TextSelection {
            base: 0,
            extent: 0,
            affinity: ui_input::TextAffinity::Upstream,
        },
        composing: ui_input::TextRange { start: -1, end: -1 },
    }
}

// Measure text in utf16 code units.
pub fn measure_utf16(s: &str) -> usize {
    s.chars().map(|c| c.len_utf16()).sum::<usize>()
}

// Setup IME text edit state using contents and selection indices.
pub async fn setup_ime(
    ime: &ui_input::InputMethodEditorProxy,
    text: &str,
    base: i64,
    extent: i64,
) -> Result<()> {
    let mut state = default_state();
    state.text = text.to_string();
    state.selection.base = base;
    state.selection.extent = extent;

    ime.set_state(&state).map_err(Into::into)
}

// Bind a new IME to the service.
pub fn bind_editor(
    ime_service: &ui_input::ImeServiceProxy,
) -> Result<(ui_input::InputMethodEditorProxy, ui_input::InputMethodEditorClientRequestStream)> {
    let (ime, ime_server_end) =
        fidl::endpoints::create_proxy::<ui_input::InputMethodEditorMarker>().unwrap();
    let (editor_client_end, editor_request_stream) =
        fidl::endpoints::create_request_stream().unwrap();
    ime_service.get_input_method_editor(
        ui_input::KeyboardType::Text,
        ui_input::InputMethodAction::Done,
        &default_state(),
        editor_client_end,
        ime_server_end,
    )?;

    Ok((ime, editor_request_stream))
}

/// Provides a method for dispatching keys, in case the tests need to vary
/// them.
#[async_trait]
pub trait KeyDispatcher {
    async fn dispatch(&self, event: ui_input3::KeyEvent) -> Result<bool>;
}

/// A [KeyDispatcher] that uses `fuchsia.ui.input.InputMethodEditor` to dispatch keypresses.
pub struct InputMethodEditorDispatcher<'a> {
    pub ime: &'a ui_input::InputMethodEditorProxy,
}

#[async_trait]
impl<'a> KeyDispatcher for InputMethodEditorDispatcher<'a> {
    async fn dispatch(&self, event: ui_input3::KeyEvent) -> Result<bool> {
        Ok(self.ime.dispatch_key3(&event).await?)
    }
}

/// A [KeyDispatcher] that uses `fuchsia.ui.input3.KeyEventInjector` to dispatch keypresses.
pub struct KeyEventInjectorDispatcher<'a> {
    pub key_event_injector: &'a ui_input3::KeyEventInjectorProxy,
}

#[async_trait]
impl<'a> KeyDispatcher for KeyEventInjectorDispatcher<'a> {
    async fn dispatch(&self, event: ui_input3::KeyEvent) -> Result<bool> {
        Ok(self.key_event_injector.inject(&event).await? == ui_input3::KeyEventStatus::Handled)
    }
}

/// A fixture that can use different services to send key events.  Use [KeySimulator::new] to
/// create a new instance.
///
/// # Example
///
/// ```ignore
/// let ime_service = connect_to_protocol::<ui_input::ImeServiceMarker>()
///     .context("Failed to connect to IME Service")?;
/// let key_dispatcher = test_helpers::ImeServiceKeyDispatcher { ime_service: &ime_service };
/// let key_simulator = test_helpers::KeySimulator::new(&key_dispatcher);
/// // Thereafter...
/// key_simulator.dispatch(fidl_fuchsia_ui_input3::KeyEvent{...}).await?;
/// ```
pub struct KeySimulator<'a> {
    dispatcher: &'a dyn KeyDispatcher,
}

impl<'a> KeySimulator<'a> {
    pub fn new(dispatcher: &'a dyn KeyDispatcher) -> Self {
        KeySimulator { dispatcher }
    }

    pub async fn dispatch(&self, event: ui_input3::KeyEvent) -> Result<bool> {
        self.dispatcher.dispatch(event).await
    }

    // Simulate a key press and release of `key`.
    async fn simulate_keypress(&self, key: input::Key) -> Result<()> {
        self.dispatch(ui_input3::KeyEvent {
            timestamp: Some(0),
            type_: Some(ui_input3::KeyEventType::Pressed),
            key: Some(key),
            ..Default::default()
        })
        .await?;
        self.dispatch(ui_input3::KeyEvent {
            timestamp: Some(0),
            type_: Some(ui_input3::KeyEventType::Released),
            key: Some(key),
            ..Default::default()
        })
        .await?;
        Ok(())
    }

    // Simulate keypress with `held_keys` pressed down.
    async fn simulate_ime_keypress_with_held_keys(
        &self,
        key: input::Key,
        held_keys: Vec<input::Key>,
    ) {
        let held_keys_down =
            held_keys.iter().map(|k| (ui_input3::KeyEventType::Pressed, *k)).into_iter();
        let held_keys_up =
            held_keys.iter().map(|k| (ui_input3::KeyEventType::Released, *k)).into_iter();
        let key_press_and_release =
            vec![(ui_input3::KeyEventType::Pressed, key), (ui_input3::KeyEventType::Released, key)]
                .into_iter();
        let sequence = held_keys_down.chain(key_press_and_release).chain(held_keys_up);
        stream::iter(sequence)
            .for_each(|(type_, key)| {
                self.dispatch(ui_input3::KeyEvent {
                    timestamp: Some(0),
                    type_: Some(type_),
                    key: Some(key),
                    ..Default::default()
                })
                .map(|_| ())
            })
            .await;
    }
}

// Simulate keypress by injecting an event into supplied key event injector.
pub async fn simulate_keypress(
    key_event_injector: &ui_input3::KeyEventInjectorProxy,
    key: input::Key,
) -> Result<()> {
    let key_dispatcher = KeyEventInjectorDispatcher { key_event_injector: &key_event_injector };
    let key_simulator = KeySimulator::new(&key_dispatcher);
    key_simulator.simulate_keypress(key).await
}

// Simulate keypress by injecting into IME.
pub async fn simulate_ime_keypress(ime: &ui_input::InputMethodEditorProxy, key: input::Key) {
    simulate_ime_keypress_with_held_keys(ime, key, Vec::new()).await
}

// Simulate keypress by injecting into IME, with `held_keys` pressed down.
pub async fn simulate_ime_keypress_with_held_keys(
    ime: &ui_input::InputMethodEditorProxy,
    key: input::Key,
    held_keys: Vec<input::Key>,
) {
    let key_dispatcher = InputMethodEditorDispatcher { ime: &ime };
    let key_simulator = KeySimulator::new(&key_dispatcher);
    key_simulator.simulate_ime_keypress_with_held_keys(key, held_keys).await
}

// Get next IME message, assuming it's a `InputMethodEditorClientRequest::DidUpdateState`.
pub async fn get_state_update(
    editor_stream: &mut ui_input::InputMethodEditorClientRequestStream,
) -> Result<(ui_input::TextInputState, Option<ui_input::KeyboardEvent>)> {
    editor_stream
        .map(|request| match request {
            Ok(ui_input::InputMethodEditorClientRequest::DidUpdateState {
                state, event, ..
            }) => {
                let keyboard_event = event.map(|e| {
                    if let ui_input::InputEvent::Keyboard(keyboard_event) = *e {
                        keyboard_event
                    } else {
                        panic!("expected DidUpdateState to only send Keyboard events");
                    }
                });
                Ok((state, keyboard_event))
            }
            Ok(msg) => Err(format_err!("request should be DidUpdateState, got {:?}", msg)),
            Err(err) => Err(Into::into(err)),
        })
        .try_next()
        .await
        .map(|maybe_msg| maybe_msg.ok_or(format_err!("ime should have sent message")))?
}

// Get next IME message, assuming it's a `InputMethodEditorClientRequest::OnAction`.
pub async fn get_action(
    editor_stream: &mut ui_input::InputMethodEditorClientRequestStream,
) -> Result<ui_input::InputMethodAction> {
    editor_stream
        .map(|request| match request {
            Ok(ui_input::InputMethodEditorClientRequest::OnAction { action, .. }) => Ok(action),
            Ok(msg) => Err(format_err!("request should be OnAction, got {:?}", msg)),
            Err(err) => Err(Into::into(err)),
        })
        .try_next()
        .await
        .map(|maybe_msg| maybe_msg.ok_or(format_err!("ime should have sent message")))?
}

/// Used to reduce verbosity of instantiating `KeyMeaning`s.
pub struct KeyMeaningWrapper(Option<ui_input3::KeyMeaning>);

impl From<ui_input3::KeyMeaning> for KeyMeaningWrapper {
    fn from(src: ui_input3::KeyMeaning) -> Self {
        KeyMeaningWrapper(src.into())
    }
}

impl From<Option<ui_input3::KeyMeaning>> for KeyMeaningWrapper {
    fn from(src: Option<ui_input3::KeyMeaning>) -> Self {
        KeyMeaningWrapper(src)
    }
}

impl From<KeyMeaningWrapper> for Option<ui_input3::KeyMeaning> {
    fn from(src: KeyMeaningWrapper) -> Self {
        src.0
    }
}

impl From<char> for KeyMeaningWrapper {
    fn from(src: char) -> Self {
        Some(ui_input3::KeyMeaning::Codepoint(src as u32)).into()
    }
}

impl From<ui_input3::NonPrintableKey> for KeyMeaningWrapper {
    fn from(src: ui_input3::NonPrintableKey) -> Self {
        Some(ui_input3::KeyMeaning::NonPrintableKey(src)).into()
    }
}

/// Creates a `KeyEvent` with the given parameters.
pub fn create_key_event(
    timestamp: zx::Time,
    event_type: ui_input3::KeyEventType,
    key: impl Into<Option<input::Key>>,
    modifiers: impl Into<Option<ui_input3::Modifiers>>,
    key_meaning: impl Into<KeyMeaningWrapper>,
) -> ui_input3::KeyEvent {
    let key_meaning: KeyMeaningWrapper = key_meaning.into();
    ui_input3::KeyEvent {
        timestamp: Some(timestamp.into_nanos()),
        type_: Some(event_type),
        key: key.into(),
        modifiers: modifiers.into(),
        key_meaning: key_meaning.into(),
        ..Default::default()
    }
}
