// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![cfg(test)]

use {
    anyhow::{Context as _, Result},
    assert_matches::assert_matches,
    fidl::endpoints::DiscoverableProtocolMarker,
    fidl::endpoints::{create_request_stream, ProtocolMarker as _},
    fidl_fuchsia_input as input, fidl_fuchsia_ui_input as fidl_input,
    fidl_fuchsia_ui_input3 as ui_input3, fidl_fuchsia_ui_keyboard_focus as fidl_focus,
    fidl_fuchsia_ui_views as ui_views, fuchsia_async as fasync,
    fuchsia_component_test::{
        Capability, ChildOptions, ChildRef, RealmBuilder, RealmInstance, Ref, Route,
    },
    fuchsia_scenic as scenic, fuchsia_zircon as zx,
    futures::FutureExt,
    futures::{
        future,
        stream::{FusedStream, StreamExt},
    },
    test_case::test_case,
    test_helpers::create_key_event,
};

const URL_TEXT_MANAGER: &str =
    "fuchsia-pkg://fuchsia.com/keyboard_test_parallel#meta/text_manager.cm";

// A shorthand for type safe routing the given protocol from a child to the parent.
async fn route_to_parent<P: DiscoverableProtocolMarker>(
    builder: &RealmBuilder,
    child: &ChildRef,
) -> Result<(), fuchsia_component_test::error::Error> {
    builder
        .add_route(
            Route::new().capability(Capability::protocol::<P>()).from(child).to(Ref::parent()),
        )
        .await
}

/// Wrapper for a `NestedEnvironment` that exposes the protocols offered by text_manager.
/// Running each test method in its own environment allows the tests to be run in parallel.
struct TestEnvironment {
    realm: RealmInstance,
}

impl TestEnvironment {
    async fn new() -> Result<Self> {
        let builder = RealmBuilder::new().await?;
        let text_manager =
            builder.add_child("text_manager", URL_TEXT_MANAGER, ChildOptions::new()).await?;

        route_to_parent::<ui_input3::KeyboardMarker>(&builder, &text_manager).await?;
        route_to_parent::<fidl_input::ImeServiceMarker>(&builder, &text_manager).await?;
        route_to_parent::<ui_input3::KeyEventInjectorMarker>(&builder, &text_manager).await?;
        route_to_parent::<fidl_focus::ControllerMarker>(&builder, &text_manager).await?;
        builder
            .add_route(
                Route::new()
                    .capability(Capability::protocol::<fidl_fuchsia_logger::LogSinkMarker>())
                    .from(Ref::parent())
                    .to(&text_manager),
            )
            .await?;

        let realm = builder.build().await?;

        Ok(TestEnvironment { realm })
    }

    /// Connects to the given discoverable service in the `NestedEnvironment`, with a readable
    /// context on error.
    fn connect_to_env_service<P>(&self) -> Result<P>
    where
        P: fidl::endpoints::Proxy,
        P::Protocol: fidl::endpoints::DiscoverableProtocolMarker,
    {
        let conn =
            self.realm.root.connect_to_protocol_at_exposed_dir::<P::Protocol>().with_context(
                || format!("Failed to connect to test realm's {}", P::Protocol::DEBUG_NAME),
            );
        tracing::debug!("Connected to test realm's {}", P::Protocol::DEBUG_NAME);
        conn
    }

    fn connect_to_focus_controller(&self) -> Result<fidl_focus::ControllerProxy> {
        self.connect_to_env_service::<_>()
    }

    fn connect_to_keyboard_service(&self) -> Result<ui_input3::KeyboardProxy> {
        self.connect_to_env_service::<_>()
    }

    fn connect_to_key_event_injector(&self) -> Result<ui_input3::KeyEventInjectorProxy> {
        self.connect_to_env_service::<_>()
    }
}

fn create_key_down_event(key: input::Key, modifiers: ui_input3::Modifiers) -> ui_input3::KeyEvent {
    ui_input3::KeyEvent {
        timestamp: Some(0),
        key: Some(key),
        modifiers: Some(modifiers),
        type_: Some(ui_input3::KeyEventType::Pressed),
        ..Default::default()
    }
}

fn create_key_up_event(key: input::Key, modifiers: ui_input3::Modifiers) -> ui_input3::KeyEvent {
    ui_input3::KeyEvent {
        timestamp: Some(0),
        key: Some(key),
        modifiers: Some(modifiers),
        type_: Some(ui_input3::KeyEventType::Released),
        ..Default::default()
    }
}

async fn expect_key_event(
    listener: &mut ui_input3::KeyboardListenerRequestStream,
) -> ui_input3::KeyEvent {
    let listener_request = listener.next().await;
    if let Some(Ok(ui_input3::KeyboardListenerRequest::OnKeyEvent { event, responder, .. })) =
        listener_request
    {
        responder.send(ui_input3::KeyEventStatus::Handled).expect("responding from key listener");
        event
    } else {
        panic!("Expected key event, got {:?}", listener_request);
    }
}

async fn dispatch_and_expect_key_event<'a>(
    key_dispatcher: &'a test_helpers::KeySimulator<'a>,
    listener: &mut ui_input3::KeyboardListenerRequestStream,
    event: ui_input3::KeyEvent,
) -> Result<()> {
    let (was_handled, event_result) =
        future::join(key_dispatcher.dispatch(event.clone()), expect_key_event(listener)).await;

    assert_eq!(was_handled?, true);
    assert_eq!(event_result.key, event.key);
    assert_eq!(event_result.type_, event.type_);
    Ok(())
}

async fn expect_key_and_modifiers(
    listener: &mut ui_input3::KeyboardListenerRequestStream,
    key: input::Key,
    modifiers: ui_input3::Modifiers,
) {
    let event = expect_key_event(listener).await;
    assert_eq!(event.key, Some(key));
    assert_eq!(event.modifiers, Some(modifiers));
}

async fn test_disconnecting_keyboard_client_disconnects_listener_with_connections(
    focus_ctl: fidl_focus::ControllerProxy,
    key_simulator: &'_ test_helpers::KeySimulator<'_>,
    keyboard_service_client: ui_input3::KeyboardProxy,
    keyboard_service_other_client: &ui_input3::KeyboardProxy,
) -> Result<()> {
    tracing::debug!("test_disconnecting_keyboard_client_disconnects_listener_with_connections");

    // Create fake client.
    let (listener_client_end, mut listener) =
        fidl::endpoints::create_request_stream::<ui_input3::KeyboardListenerMarker>()?;
    let view_ref = scenic::ViewRefPair::new()?.view_ref;

    keyboard_service_client
        .add_listener(scenic::duplicate_view_ref(&view_ref)?, listener_client_end)
        .await
        .expect("add_listener for first client");

    // Create another fake client.
    let (other_listener_client_end, mut other_listener) =
        fidl::endpoints::create_request_stream::<ui_input3::KeyboardListenerMarker>()?;
    let other_view_ref = scenic::ViewRefPair::new()?.view_ref;

    keyboard_service_other_client
        .add_listener(scenic::duplicate_view_ref(&other_view_ref)?, other_listener_client_end)
        .await
        .expect("add_listener for another client");

    // Focus second client.
    focus_ctl.notify(scenic::duplicate_view_ref(&other_view_ref)?).await?;

    // Drop proxy, emulating first client disconnecting from it.
    std::mem::drop(keyboard_service_client);

    // Expect disconnected client key event listener to be disconnected as well.
    assert_matches!(listener.next().await, None);
    assert_matches!(listener.is_terminated(), true);

    // Ensure that the other client is still connected.
    let (key, modifiers) = (input::Key::A, ui_input3::Modifiers::CAPS_LOCK);
    let dispatched_event = create_key_down_event(key, modifiers);

    let (was_handled, _) = future::join(
        key_simulator.dispatch(dispatched_event),
        expect_key_and_modifiers(&mut other_listener, key, modifiers),
    )
    .await;

    assert_eq!(was_handled?, true);

    let dispatched_event = create_key_up_event(key, modifiers);
    let (was_handled, _) = future::join(
        key_simulator.dispatch(dispatched_event),
        expect_key_and_modifiers(&mut other_listener, key, modifiers),
    )
    .await;

    assert_eq!(was_handled?, true);
    Ok(())
}

#[fuchsia::test(logging_tags = ["keyboard3_integration_test"])]
async fn test_disconnecting_keyboard_client_disconnects_listener_via_key_event_injector(
) -> Result<()> {
    let test_env = TestEnvironment::new().await?;

    let key_event_injector = test_env.connect_to_key_event_injector()?;

    let key_dispatcher =
        test_helpers::KeyEventInjectorDispatcher { key_event_injector: &key_event_injector };
    let key_simulator = test_helpers::KeySimulator::new(&key_dispatcher);

    let keyboard_service_client_a = test_env.connect_to_keyboard_service().context("client_a")?;

    let keyboard_service_client_b = test_env.connect_to_keyboard_service().context("client_b")?;

    test_disconnecting_keyboard_client_disconnects_listener_with_connections(
        test_env.connect_to_focus_controller()?,
        &key_simulator,
        // This one will be dropped as part of the test, so needs to be moved.
        keyboard_service_client_a,
        &keyboard_service_client_b,
    )
    .await?;

    Ok(())
}

async fn test_sync_cancel_with_connections(
    focus_ctl: fidl_focus::ControllerProxy,
    key_simulator: &'_ test_helpers::KeySimulator<'_>,
    keyboard_service_client_a: &ui_input3::KeyboardProxy,
    keyboard_service_client_b: &ui_input3::KeyboardProxy,
) -> Result<()> {
    // Create fake client.
    let (listener_client_end_a, mut listener_a) =
        fidl::endpoints::create_request_stream::<ui_input3::KeyboardListenerMarker>()?;
    let view_ref_a = scenic::ViewRefPair::new()?.view_ref;

    keyboard_service_client_a
        .add_listener(scenic::duplicate_view_ref(&view_ref_a)?, listener_client_end_a)
        .await
        .expect("add_listener for first client");

    // Create another fake client.
    let (listener_client_end_b, mut listener_b) =
        fidl::endpoints::create_request_stream::<ui_input3::KeyboardListenerMarker>()?;
    let view_ref_b = scenic::ViewRefPair::new()?.view_ref;

    keyboard_service_client_b
        .add_listener(scenic::duplicate_view_ref(&view_ref_b)?, listener_client_end_b)
        .await
        .expect("add_listener for another client");

    let key1 = input::Key::A;
    let event1_press = ui_input3::KeyEvent {
        timestamp: Some(0),
        key: Some(key1),
        type_: Some(ui_input3::KeyEventType::Pressed),
        ..Default::default()
    };
    let event1_release = ui_input3::KeyEvent {
        timestamp: Some(0),
        key: Some(key1),
        type_: Some(ui_input3::KeyEventType::Released),
        ..Default::default()
    };

    // Focus client A.
    focus_ctl.notify(scenic::duplicate_view_ref(&view_ref_a)?).await?;

    // Press the key and expect client A to receive the event.
    dispatch_and_expect_key_event(&key_simulator, &mut listener_a, event1_press).await?;

    assert!(listener_b.next().now_or_never().is_none(), "listener_b should have no events yet");

    // Focus client B.
    // Expect a cancel event for client A and a sync event for the client B.
    let (focus_result, client_a_event, client_b_event) = future::join3(
        focus_ctl.notify(scenic::duplicate_view_ref(&view_ref_b)?),
        expect_key_event(&mut listener_a),
        expect_key_event(&mut listener_b),
    )
    .await;

    focus_result?;

    assert_eq!(
        ui_input3::KeyEvent {
            timestamp: Some(0i64),
            key: Some(input::Key::A),
            type_: Some(ui_input3::KeyEventType::Cancel),
            ..Default::default()
        },
        client_a_event
    );

    assert_eq!(
        ui_input3::KeyEvent {
            timestamp: Some(0i64),
            key: Some(input::Key::A),
            type_: Some(ui_input3::KeyEventType::Sync),
            ..Default::default()
        },
        client_b_event
    );

    // Release the key and expect client B to receive an event.
    dispatch_and_expect_key_event(&key_simulator, &mut listener_b, event1_release).await?;

    assert!(listener_a.next().now_or_never().is_none(), "listener_a should have no more events");

    // Focus client A again.
    focus_ctl.notify(scenic::duplicate_view_ref(&view_ref_a)?).await?;

    assert!(
        listener_a.next().now_or_never().is_none(),
        "listener_a should have no more events after receiving focus"
    );

    Ok(())
}

#[fuchsia::test(logging_tags = ["keyboard3_integration_test"])]
async fn test_sync_cancel_via_key_event_injector() -> Result<()> {
    let test_env = TestEnvironment::new().await?;

    // This test dispatches keys via KeyEventInjector.
    let key_event_injector = test_env.connect_to_key_event_injector()?;

    let key_dispatcher =
        test_helpers::KeyEventInjectorDispatcher { key_event_injector: &key_event_injector };
    let key_simulator = test_helpers::KeySimulator::new(&key_dispatcher);

    let keyboard_service_client_a = test_env.connect_to_keyboard_service().context("client_a")?;

    let keyboard_service_client_b = test_env.connect_to_keyboard_service().context("client_b")?;

    test_sync_cancel_with_connections(
        test_env.connect_to_focus_controller()?,
        &key_simulator,
        &keyboard_service_client_a,
        &keyboard_service_client_b,
    )
    .await
}

struct TestHandles {
    _test_env: TestEnvironment,
    _keyboard_service: ui_input3::KeyboardProxy,
    listener_stream: ui_input3::KeyboardListenerRequestStream,
    injector_service: ui_input3::KeyEventInjectorProxy,
    _view_ref: ui_views::ViewRef,
}

impl TestHandles {
    async fn new() -> Result<TestHandles> {
        let _test_env = TestEnvironment::new().await?;

        // Create fake client.
        let (listener_client_end, listener_stream) = create_request_stream::<
            ui_input3::KeyboardListenerMarker,
        >()
        .with_context(|| {
            format!("create_request_stream for {}", ui_input3::KeyboardListenerMarker::DEBUG_NAME)
        })?;
        let _view_ref = scenic::ViewRefPair::new()?.view_ref;

        let _keyboard_service: ui_input3::KeyboardProxy =
            _test_env.connect_to_keyboard_service()?;
        _keyboard_service
            .add_listener(scenic::duplicate_view_ref(&_view_ref)?, listener_client_end)
            .await
            .expect("add_listener");

        let focus_controller = _test_env.connect_to_focus_controller()?;
        focus_controller.notify(scenic::duplicate_view_ref(&_view_ref)?).await?;

        let injector_service = _test_env.connect_to_key_event_injector()?;

        Ok(TestHandles {
            _test_env,
            _keyboard_service,
            listener_stream,
            injector_service,
            _view_ref,
        })
    }
}

fn inject_key_and_receive_keyboard_protocol_message(
    event: ui_input3::KeyEvent,
) -> Result<(Result<ui_input3::KeyEventStatus, fidl::Error>, ui_input3::KeyEvent)> {
    fasync::TestExecutor::new().run_singlethreaded(async {
        let mut handles = TestHandles::new().await?;

        let (was_handled, received_event) = future::join(
            handles.injector_service.inject(&event),
            expect_key_event(&mut handles.listener_stream),
        )
        .await;
        Ok((was_handled, received_event))
    })
}

#[test_case(input::Key::A, None => (Some(input::Key::A), None); "without_key_meaning")]
#[test_case(input::Key::A, 'a'
             => (Some(input::Key::A), Some(ui_input3::KeyMeaning::Codepoint(0x61)));
            "key_and_meaning")]
#[test_case(None, 'a'
            => (None, Some(ui_input3::KeyMeaning::Codepoint(0x61)));
            "only_key_meaning_lower_alpha")]
#[test_case(None, 'A'
            => (None, Some(ui_input3::KeyMeaning::Codepoint(0x41)));
            "only_key_meaning_upper_alpha")]
#[test_case(None, '1'
            => (None, Some(ui_input3::KeyMeaning::Codepoint(0x31)));
            "only_key_meaning_numeric")]
#[test_case(None, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Enter)
            => (Some(input::Key::Enter),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Enter)));
            "only_key_meaning_enter")]
#[test_case(None, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Tab)
            => (Some(input::Key::Tab),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Tab)));
            "only_key_meaning_tab")]
#[test_case(None, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Backspace)
            => (Some(input::Key::Backspace),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Backspace)));
            "only_key_meaning_backspace")]
#[test_case(input::Key::Down, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Down)
            => (Some(input::Key::Down),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Down)));
            "arrow_down")]
#[test_case(None, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Down)
            => (None,
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Down)));
            "only_key_meaning_arrow_down")]
#[test_case(input::Key::Up, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Up)
            => (Some(input::Key::Up),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Up)));
            "arrow_up")]
#[test_case(input::Key::Left, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Left)
            => (Some(input::Key::Left),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Left)));
            "arrow_left")]
#[test_case(input::Key::Right, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Right)
            => (Some(input::Key::Right),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Right)));
            "arrow_right")]
#[test_case(input::Key::End, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::End)
            => (Some(input::Key::End),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::End)));
            "end")]
#[test_case(input::Key::Home, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Home)
            => (Some(input::Key::Home),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::Home)));
            "home")]
#[test_case(input::Key::PageDown, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::PageDown)
            => (Some(input::Key::PageDown),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::PageDown)));
            "page_down")]
#[test_case(input::Key::PageUp, ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::PageUp)
            => (Some(input::Key::PageUp),
                Some(ui_input3::KeyMeaning::NonPrintableKey(ui_input3::NonPrintableKey::PageUp)));
            "page_up")]
fn test_inject_key_yields_expected_key_and_key_meaning(
    key: impl Into<Option<input::Key>>,
    key_meaning: impl Into<test_helpers::KeyMeaningWrapper>,
) -> (Option<input::Key>, Option<ui_input3::KeyMeaning>) {
    let (was_handled, received_event) = inject_key_and_receive_keyboard_protocol_message(
        create_key_event(zx::Time::ZERO, ui_input3::KeyEventType::Pressed, key, None, key_meaning),
    )
    .expect("injection failed");
    assert_matches::assert_matches!(was_handled, Ok(ui_input3::KeyEventStatus::Handled));
    (received_event.key, received_event.key_meaning)
}
