// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/linux/fl_keyboard_manager.h"

#include <cstring>

#include "flutter/shell/platform/linux/testing/mock_text_input_plugin.h"
#include "gtest/gtest.h"

#define FL_KEY_EVENT(target) reinterpret_cast<FlKeyEvent*>(target)

namespace {
typedef void (*CallbackHandler)(FlKeyResponderAsyncCallback callback,
                                gpointer user_data);

constexpr guint16 kKeyCodeKeyA = 0x26u;
constexpr guint16 kKeyCodeKeyB = 0x38u;

G_DECLARE_FINAL_TYPE(FlKeyboardCallRecord,
                     fl_keyboard_call_record,
                     FL,
                     KEYBOARD_CALL_RECORD,
                     GObject);

typedef struct _FlKeyMockResponder FlKeyMockResponder;
struct _FlKeyboardCallRecord {
  GObject parent_instance;

  FlKeyMockResponder* responder;
  FlKeyEvent* event;
  FlKeyResponderAsyncCallback callback;
  gpointer user_data;
};

#define FL_TYPE_KEY_MOCK_RESPONDER fl_key_mock_responder_get_type()
G_DECLARE_FINAL_TYPE(FlKeyMockResponder,
                     fl_key_mock_responder,
                     FL,
                     KEY_MOCK_RESPONDER,
                     GObject);

struct _FlKeyMockResponder {
  GObject parent_instance;

  // A weak pointer for a list of FlKeyboardCallRecord.
  GPtrArray* call_records;
  CallbackHandler callback_handler;
  int delegate_id;
};

G_DEFINE_TYPE(FlKeyboardCallRecord, fl_keyboard_call_record, G_TYPE_OBJECT)

static void fl_keyboard_call_record_init(FlKeyboardCallRecord* self) {}

// Dispose method for FlKeyboardCallRecord.
static void fl_keyboard_call_record_dispose(GObject* object) {
  g_return_if_fail(FL_IS_KEYBOARD_CALL_RECORD(object));

  FlKeyboardCallRecord* self = FL_KEYBOARD_CALL_RECORD(object);
  fl_key_event_dispose(self->event);
  G_OBJECT_CLASS(fl_keyboard_call_record_parent_class)->dispose(object);
}

// Class Initialization method for FlKeyboardCallRecord class.
static void fl_keyboard_call_record_class_init(
    FlKeyboardCallRecordClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_keyboard_call_record_dispose;
}

static FlKeyboardCallRecord* fl_keyboard_call_record_new(
    FlKeyMockResponder* responder,
    FlKeyEvent* event,
    FlKeyResponderAsyncCallback callback,
    gpointer user_data) {
  g_return_val_if_fail(FL_IS_KEY_MOCK_RESPONDER(responder), nullptr);
  g_return_val_if_fail(event != nullptr, nullptr);
  g_return_val_if_fail(callback != nullptr, nullptr);
  g_return_val_if_fail(user_data != nullptr, nullptr);

  FlKeyboardCallRecord* self = FL_KEYBOARD_CALL_RECORD(
      g_object_new(fl_keyboard_call_record_get_type(), nullptr));

  self->responder = responder;
  self->event = event;
  self->callback = callback;
  self->user_data = user_data;

  return self;
}

static void dont_respond(FlKeyResponderAsyncCallback callback,
                         gpointer user_data) {}
static void respond_true(FlKeyResponderAsyncCallback callback,
                         gpointer user_data) {
  callback(true, user_data);
}
static void respond_false(FlKeyResponderAsyncCallback callback,
                          gpointer user_data) {
  callback(false, user_data);
}

static gboolean filter_keypress_returns_true(FlTextInputPlugin* self,
                                             FlKeyEvent* event) {
  return TRUE;
}

static gboolean filter_keypress_returns_false(FlTextInputPlugin* self,
                                              FlKeyEvent* event) {
  return FALSE;
}

static void fl_key_mock_responder_iface_init(FlKeyResponderInterface* iface);

G_DEFINE_TYPE_WITH_CODE(FlKeyMockResponder,
                        fl_key_mock_responder,
                        G_TYPE_OBJECT,
                        G_IMPLEMENT_INTERFACE(FL_TYPE_KEY_RESPONDER,
                                              fl_key_mock_responder_iface_init))

static void fl_key_mock_responder_handle_event(
    FlKeyResponder* responder,
    FlKeyEvent* event,
    FlKeyResponderAsyncCallback callback,
    gpointer user_data);

static void fl_key_mock_responder_iface_init(FlKeyResponderInterface* iface) {
  iface->handle_event = fl_key_mock_responder_handle_event;
}

// Return a newly allocated #FlKeyEvent that is a clone to the given #event
// but with #origin and #dispose set to 0.
static FlKeyEvent* fl_key_event_clone_information_only(FlKeyEvent* event) {
  FlKeyEvent* new_event = fl_key_event_clone(event);
  new_event->origin = nullptr;
  new_event->dispose_origin = nullptr;
  return new_event;
}
static void fl_key_mock_responder_handle_event(
    FlKeyResponder* responder,
    FlKeyEvent* event,
    FlKeyResponderAsyncCallback callback,
    gpointer user_data) {
  FlKeyMockResponder* self = FL_KEY_MOCK_RESPONDER(responder);
  g_ptr_array_add(self->call_records,
                  FL_KEYBOARD_CALL_RECORD(fl_keyboard_call_record_new(
                      self, fl_key_event_clone_information_only(event),
                      callback, user_data)));
  self->callback_handler(callback, user_data);
}

static void fl_key_mock_responder_class_init(FlKeyMockResponderClass* klass) {}

static void fl_key_mock_responder_init(FlKeyMockResponder* self) {}

static FlKeyMockResponder* fl_key_mock_responder_new(GPtrArray* call_records,
                                                     int delegate_id) {
  FlKeyMockResponder* self = FL_KEY_MOCK_RESPONDER(
      g_object_new(fl_key_mock_responder_get_type(), nullptr));

  self->call_records = call_records;
  self->callback_handler = dont_respond;
  self->delegate_id = delegate_id;

  return self;
}

static void g_ptr_array_clear(GPtrArray* array) {
  g_ptr_array_remove_range(array, 0, array->len);
}

static gpointer g_ptr_array_last(GPtrArray* array) {
  return g_ptr_array_index(array, array->len - 1);
}

static void fl_key_event_free_origin_by_mock(gpointer origin) {
  g_free(origin);
}
// Create a new #FlKeyEvent with the given information.
//
// The #origin will be another #FlKeyEvent with the exact information,
// so that it can be used to redispatch, and is freed upon disposal.
static FlKeyEvent* fl_key_event_new_by_mock(bool is_press,
                                            guint keyval,
                                            guint16 keycode,
                                            int state,
                                            gboolean is_modifier) {
  FlKeyEvent* event = g_new(FlKeyEvent, 1);
  event->is_press = is_press;
  event->time = 0;
  event->state = state;
  event->keyval = keyval;
  event->string = nullptr;
  event->keycode = keycode;
  FlKeyEvent* origin_event = fl_key_event_clone_information_only(event);
  event->origin = origin_event;
  event->dispose_origin = fl_key_event_free_origin_by_mock;
  return event;
}

namespace {
// A global variable to store redispatched #FlKeyEvent. It is a global variable
// so that it can be used in a function without user_data.
//
// This array does not free elements upon removal.
GPtrArray* _g_redispatched_events;
}  // namespace

static GPtrArray* redispatched_events() {
  if (_g_redispatched_events == nullptr) {
    _g_redispatched_events = g_ptr_array_new();
  }
  return _g_redispatched_events;
}
static void store_redispatched_event(gpointer event) {
  FlKeyEvent* new_event = g_new(FlKeyEvent, 1);
  *new_event = *reinterpret_cast<FlKeyEvent*>(event);
  g_ptr_array_add(redispatched_events(), new_event);
}

// Make sure that the keyboard can be disposed without crashes when there are
// unresolved pending events.
TEST(FlKeyboardManagerTest, DisposeWithUnresolvedPends) {
  FlKeyboardManager* manager =
      fl_keyboard_manager_new(nullptr, store_redispatched_event);

  GPtrArray* call_records = g_ptr_array_new_with_free_func(g_object_unref);
  FlKeyMockResponder* responder = fl_key_mock_responder_new(call_records, 1);
  fl_keyboard_manager_add_responder(manager, FL_KEY_RESPONDER(responder));

  responder->callback_handler = dont_respond;
  fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));

  responder->callback_handler = respond_true;
  fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));

  // Passes if the cleanup of `manager` does not crash.
  g_object_unref(manager);
  g_ptr_array_unref(call_records);
}

TEST(FlKeyboardManagerTest, SingleDelegateWithAsyncResponds) {
  GPtrArray* call_records = g_ptr_array_new_with_free_func(g_object_unref);
  FlKeyboardCallRecord* record;

  gboolean manager_handled = false;
  g_autoptr(FlKeyboardManager) manager =
      fl_keyboard_manager_new(nullptr, store_redispatched_event);
  fl_keyboard_manager_add_responder(
      manager, FL_KEY_RESPONDER(fl_key_mock_responder_new(call_records, 1)));

  /// Test 1: One event that is handled by the framework

  // Dispatch a key event
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));
  EXPECT_EQ(manager_handled, true);
  EXPECT_EQ(redispatched_events()->len, 0u);
  EXPECT_EQ(call_records->len, 1u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  EXPECT_EQ(record->responder->delegate_id, 1);
  EXPECT_EQ(record->event->keyval, 0x61u);
  EXPECT_EQ(record->event->keycode, 0x26u);

  record->callback(true, record->user_data);
  EXPECT_EQ(redispatched_events()->len, 0u);

  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));
  g_ptr_array_clear(call_records);

  /// Test 2: Two events that are unhandled by the framework
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));
  EXPECT_EQ(manager_handled, true);
  EXPECT_EQ(redispatched_events()->len, 0u);
  EXPECT_EQ(call_records->len, 1u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  EXPECT_EQ(record->responder->delegate_id, 1);
  EXPECT_EQ(record->event->keyval, 0x61u);
  EXPECT_EQ(record->event->keycode, 0x26u);

  // Dispatch another key event
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_b, kKeyCodeKeyB, 0x10, false));
  EXPECT_EQ(manager_handled, true);
  EXPECT_EQ(redispatched_events()->len, 0u);
  EXPECT_EQ(call_records->len, 2u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 1));
  EXPECT_EQ(record->responder->delegate_id, 1);
  EXPECT_EQ(record->event->keyval, 0x62u);
  EXPECT_EQ(record->event->keycode, 0x38u);

  // Resolve the second event first to test out-of-order response
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 1));
  record->callback(false, record->user_data);
  EXPECT_EQ(redispatched_events()->len, 1u);
  EXPECT_EQ(FL_KEY_EVENT(g_ptr_array_last(redispatched_events()))->keyval,
            0x62u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  record->callback(false, record->user_data);
  EXPECT_EQ(redispatched_events()->len, 2u);
  EXPECT_EQ(FL_KEY_EVENT(g_ptr_array_last(redispatched_events()))->keyval,
            0x61u);

  g_ptr_array_clear(call_records);

  // Resolve redispatches
  manager_handled = fl_keyboard_manager_handle_event(
      manager, FL_KEY_EVENT(g_ptr_array_index(redispatched_events(), 0)));
  EXPECT_EQ(manager_handled, false);
  manager_handled = fl_keyboard_manager_handle_event(
      manager, FL_KEY_EVENT(g_ptr_array_index(redispatched_events(), 1)));
  EXPECT_EQ(manager_handled, false);
  EXPECT_EQ(call_records->len, 0u);

  g_ptr_array_clear(redispatched_events());
  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));

  /// Test 3: Dispatch the same event again to ensure that prevention from
  /// redispatching only works once.
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));
  EXPECT_EQ(manager_handled, true);
  EXPECT_EQ(redispatched_events()->len, 0u);
  EXPECT_EQ(call_records->len, 1u);

  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  record->callback(true, record->user_data);

  g_ptr_array_clear(redispatched_events());
  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));
  g_ptr_array_unref(call_records);
}

TEST(FlKeyboardManagerTest, SingleDelegateWithSyncResponds) {
  GPtrArray* call_records = g_ptr_array_new_with_free_func(g_object_unref);
  FlKeyboardCallRecord* record;

  gboolean manager_handled = false;
  g_autoptr(FlKeyboardManager) manager =
      fl_keyboard_manager_new(nullptr, store_redispatched_event);
  FlKeyMockResponder* responder = fl_key_mock_responder_new(call_records, 1);
  fl_keyboard_manager_add_responder(manager, FL_KEY_RESPONDER(responder));

  /// Test 1: One event that is handled by the framework

  // Dispatch a key event
  responder->callback_handler = respond_true;
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));
  EXPECT_EQ(manager_handled, true);
  EXPECT_EQ(call_records->len, 1u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  EXPECT_EQ(record->responder->delegate_id, 1);
  EXPECT_EQ(record->event->keyval, 0x61u);
  EXPECT_EQ(record->event->keycode, 0x26u);
  EXPECT_EQ(redispatched_events()->len, 0u);

  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));

  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));
  g_ptr_array_clear(call_records);

  /// Test 2: An event unhandled by the framework
  responder->callback_handler = respond_false;
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));
  EXPECT_EQ(manager_handled, true);
  EXPECT_EQ(call_records->len, 1u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  EXPECT_EQ(record->responder->delegate_id, 1);
  EXPECT_EQ(record->event->keyval, 0x61u);
  EXPECT_EQ(record->event->keycode, 0x26u);
  EXPECT_EQ(redispatched_events()->len, 1u);

  g_ptr_array_clear(call_records);

  // Resolve redispatch
  manager_handled = fl_keyboard_manager_handle_event(
      manager, FL_KEY_EVENT(g_ptr_array_index(redispatched_events(), 0)));
  EXPECT_EQ(manager_handled, false);
  EXPECT_EQ(call_records->len, 0u);

  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));
  g_ptr_array_clear(redispatched_events());
  g_ptr_array_unref(call_records);
}

TEST(FlKeyboardManagerTest, WithTwoAsyncDelegates) {
  GPtrArray* call_records = g_ptr_array_new_with_free_func(g_object_unref);
  FlKeyboardCallRecord* record;

  gboolean manager_handled = false;
  g_autoptr(FlKeyboardManager) manager =
      fl_keyboard_manager_new(nullptr, store_redispatched_event);
  fl_keyboard_manager_add_responder(
      manager, FL_KEY_RESPONDER(fl_key_mock_responder_new(call_records, 1)));
  fl_keyboard_manager_add_responder(
      manager, FL_KEY_RESPONDER(fl_key_mock_responder_new(call_records, 2)));

  /// Test 1: One delegate responds true, the other false

  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));

  EXPECT_EQ(manager_handled, true);
  EXPECT_EQ(redispatched_events()->len, 0u);
  EXPECT_EQ(call_records->len, 2u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  EXPECT_EQ(record->responder->delegate_id, 1);
  EXPECT_EQ(record->event->keyval, 0x61u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 1));
  EXPECT_EQ(record->responder->delegate_id, 2);
  EXPECT_EQ(record->event->keyval, 0x61u);

  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  record->callback(true, record->user_data);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 1));
  record->callback(false, record->user_data);
  EXPECT_EQ(redispatched_events()->len, 0u);

  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));
  g_ptr_array_clear(call_records);

  /// Test 2: All delegates respond false
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0x10, false));

  EXPECT_EQ(manager_handled, true);
  EXPECT_EQ(redispatched_events()->len, 0u);
  EXPECT_EQ(call_records->len, 2u);

  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 0));
  record->callback(false, record->user_data);
  EXPECT_EQ(redispatched_events()->len, 0u);
  record = FL_KEYBOARD_CALL_RECORD(g_ptr_array_index(call_records, 1));
  record->callback(false, record->user_data);
  EXPECT_EQ(redispatched_events()->len, 1u);

  g_ptr_array_clear(call_records);

  // Resolve redispatch
  manager_handled = fl_keyboard_manager_handle_event(
      manager, FL_KEY_EVENT(g_ptr_array_index(redispatched_events(), 0)));
  EXPECT_EQ(manager_handled, false);
  EXPECT_EQ(call_records->len, 0u);

  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));
  g_ptr_array_clear(call_records);

  g_ptr_array_clear(redispatched_events());
  g_ptr_array_unref(call_records);
}

TEST(FlKeyboardManagerTest, TextInputPluginReturnsFalse) {
  GPtrArray* call_records = g_ptr_array_new_with_free_func(g_object_unref);

  gboolean manager_handled = false;
  // The text input plugin doesn't handle events.
  g_autoptr(FlKeyboardManager) manager = fl_keyboard_manager_new(
      FL_TEXT_INPUT_PLUGIN(
          fl_mock_text_input_plugin_new(filter_keypress_returns_false)),
      store_redispatched_event);

  // The responder never handles events.
  FlKeyMockResponder* responder = fl_key_mock_responder_new(call_records, 1);
  fl_keyboard_manager_add_responder(manager, FL_KEY_RESPONDER(responder));
  responder->callback_handler = respond_false;

  // Dispatch a key event.
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0, false));
  EXPECT_EQ(manager_handled, true);
  // The event was redispatched because no one handles it.
  EXPECT_EQ(redispatched_events()->len, 1u);

  // Resolve redispatched event.
  manager_handled = fl_keyboard_manager_handle_event(
      manager, FL_KEY_EVENT(g_ptr_array_index(redispatched_events(), 0)));
  EXPECT_EQ(manager_handled, false);

  g_ptr_array_clear(redispatched_events());
  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));
  g_ptr_array_unref(call_records);
}

TEST(FlKeyboardManagerTest, TextInputPluginReturnsTrue) {
  GPtrArray* call_records = g_ptr_array_new_with_free_func(g_object_unref);

  gboolean manager_handled = false;
  g_autoptr(FlKeyboardManager) manager = fl_keyboard_manager_new(
      FL_TEXT_INPUT_PLUGIN(
          fl_mock_text_input_plugin_new(filter_keypress_returns_true)),
      store_redispatched_event);

  // The responder never handles events.
  FlKeyMockResponder* responder = fl_key_mock_responder_new(call_records, 1);
  fl_keyboard_manager_add_responder(manager, FL_KEY_RESPONDER(responder));
  responder->callback_handler = respond_false;

  // Dispatch a key event.
  manager_handled = fl_keyboard_manager_handle_event(
      manager,
      fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0, false));
  EXPECT_EQ(manager_handled, true);
  // The event was not redispatched because text input plugin handles it.
  EXPECT_EQ(redispatched_events()->len, 0u);

  EXPECT_TRUE(fl_keyboard_manager_is_state_clear(manager));
  g_ptr_array_unref(call_records);
}

}  // namespace
