// 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_key_channel_responder.h"

#include <gtk/gtk.h>
#include <cinttypes>

#include "flutter/shell/platform/linux/public/flutter_linux/fl_basic_message_channel.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"

static constexpr char kChannelName[] = "flutter/keyevent";
static constexpr char kTypeKey[] = "type";
static constexpr char kTypeValueUp[] = "keyup";
static constexpr char kTypeValueDown[] = "keydown";
static constexpr char kKeymapKey[] = "keymap";
static constexpr char kKeyCodeKey[] = "keyCode";
static constexpr char kScanCodeKey[] = "scanCode";
static constexpr char kModifiersKey[] = "modifiers";
static constexpr char kToolkitKey[] = "toolkit";
static constexpr char kUnicodeScalarValuesKey[] = "unicodeScalarValues";

static constexpr char kGtkToolkit[] = "gtk";
static constexpr char kLinuxKeymap[] = "linux";

/* Declare and define FlKeyChannelUserData */

/**
 * FlKeyChannelUserData:
 * The user_data used when #FlKeyChannelResponder sends message through the
 * channel.
 */
G_DECLARE_FINAL_TYPE(FlKeyChannelUserData,
                     fl_key_channel_user_data,
                     FL,
                     KEY_CHANNEL_USER_DATA,
                     GObject);

struct _FlKeyChannelUserData {
  GObject parent_instance;

  // The current responder.
  FlKeyChannelResponder* responder;
  // The callback provided by the caller #FlKeyboardManager.
  FlKeyResponderAsyncCallback callback;
  // The user_data provided by the caller #FlKeyboardManager.
  gpointer user_data;
};

// Definition for FlKeyChannelUserData private class.
G_DEFINE_TYPE(FlKeyChannelUserData, fl_key_channel_user_data, G_TYPE_OBJECT)

// Dispose method for FlKeyChannelUserData private class.
static void fl_key_channel_user_data_dispose(GObject* object) {
  g_return_if_fail(FL_IS_KEY_CHANNEL_USER_DATA(object));
  FlKeyChannelUserData* self = FL_KEY_CHANNEL_USER_DATA(object);
  if (self->responder != nullptr) {
    g_object_remove_weak_pointer(
        G_OBJECT(self->responder),
        reinterpret_cast<gpointer*>(&(self->responder)));
    self->responder = nullptr;
  }
}

// Class initialization method for FlKeyChannelUserData private class.
static void fl_key_channel_user_data_class_init(
    FlKeyChannelUserDataClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_key_channel_user_data_dispose;
}

// Instance initialization method for FlKeyChannelUserData private class.
static void fl_key_channel_user_data_init(FlKeyChannelUserData* self) {}

// Creates a new FlKeyChannelUserData private class with all information.
//
// The callback and the user_data might be nullptr.
static FlKeyChannelUserData* fl_key_channel_user_data_new(
    FlKeyChannelResponder* responder,
    FlKeyResponderAsyncCallback callback,
    gpointer user_data) {
  FlKeyChannelUserData* self = FL_KEY_CHANNEL_USER_DATA(
      g_object_new(fl_key_channel_user_data_get_type(), nullptr));

  self->responder = responder;
  // Add a weak pointer so we can know if the key event responder disappeared
  // while the framework was responding.
  g_object_add_weak_pointer(G_OBJECT(responder),
                            reinterpret_cast<gpointer*>(&(self->responder)));
  self->callback = callback;
  self->user_data = user_data;
  return self;
}

/* Define FlKeyChannelResponder */

// Definition of the FlKeyChannelResponder GObject class.
struct _FlKeyChannelResponder {
  GObject parent_instance;

  FlBasicMessageChannel* channel;

  FlKeyChannelResponderMock* mock;
};

static void fl_key_channel_responder_iface_init(FlKeyResponderInterface* iface);

G_DEFINE_TYPE_WITH_CODE(
    FlKeyChannelResponder,
    fl_key_channel_responder,
    G_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE(FL_TYPE_KEY_RESPONDER,
                          fl_key_channel_responder_iface_init))

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

static void fl_key_channel_responder_iface_init(
    FlKeyResponderInterface* iface) {
  iface->handle_event = fl_key_channel_responder_handle_event;
}

/* Implement FlKeyChannelResponder */

// Handles a response from the method channel to a key event sent to the
// framework earlier.
static void handle_response(GObject* object,
                            GAsyncResult* result,
                            gpointer user_data) {
  g_autoptr(FlKeyChannelUserData) data = FL_KEY_CHANNEL_USER_DATA(user_data);

  // This is true if the weak pointer has been destroyed.
  if (data->responder == nullptr) {
    return;
  }

  FlKeyChannelResponder* self = data->responder;

  g_autoptr(GError) error = nullptr;
  FlBasicMessageChannel* messageChannel = FL_BASIC_MESSAGE_CHANNEL(object);
  FlValue* message =
      fl_basic_message_channel_send_finish(messageChannel, result, &error);
  if (self->mock != nullptr && self->mock->value_converter != nullptr) {
    message = self->mock->value_converter(message);
  }
  bool handled = false;
  if (error != nullptr) {
    g_warning("Unable to retrieve framework response: %s", error->message);
  } else {
    g_autoptr(FlValue) handled_value =
        fl_value_lookup_string(message, "handled");
    handled = fl_value_get_bool(handled_value);
  }

  data->callback(handled, data->user_data);
}

// Disposes of an FlKeyChannelResponder instance.
static void fl_key_channel_responder_dispose(GObject* object) {
  FlKeyChannelResponder* self = FL_KEY_CHANNEL_RESPONDER(object);

  g_clear_object(&self->channel);

  G_OBJECT_CLASS(fl_key_channel_responder_parent_class)->dispose(object);
}

// Initializes the FlKeyChannelResponder class methods.
static void fl_key_channel_responder_class_init(
    FlKeyChannelResponderClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_key_channel_responder_dispose;
}

// Initializes an FlKeyChannelResponder instance.
static void fl_key_channel_responder_init(FlKeyChannelResponder* self) {}

// Creates a new FlKeyChannelResponder instance, with a messenger used to send
// messages to the framework, and an FlTextInputPlugin that is used to handle
// key events that the framework doesn't handle. Mainly for testing purposes, it
// also takes an optional callback to call when a response is received, and an
// optional channel name to use when sending messages.
FlKeyChannelResponder* fl_key_channel_responder_new(
    FlBinaryMessenger* messenger,
    FlKeyChannelResponderMock* mock) {
  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);

  FlKeyChannelResponder* self = FL_KEY_CHANNEL_RESPONDER(
      g_object_new(fl_key_channel_responder_get_type(), nullptr));
  self->mock = mock;

  g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
  const char* channel_name =
      mock == nullptr ? kChannelName : mock->channel_name;
  self->channel = fl_basic_message_channel_new(messenger, channel_name,
                                               FL_MESSAGE_CODEC(codec));

  return self;
}

// Sends a key event to the framework.
static void fl_key_channel_responder_handle_event(
    FlKeyResponder* responder,
    FlKeyEvent* event,
    FlKeyResponderAsyncCallback callback,
    gpointer user_data) {
  FlKeyChannelResponder* self = FL_KEY_CHANNEL_RESPONDER(responder);
  g_return_if_fail(event != nullptr);
  g_return_if_fail(callback != nullptr);

  const gchar* type = event->is_press ? kTypeValueDown : kTypeValueUp;
  int64_t scan_code = event->keycode;
  int64_t unicode_scarlar_values = gdk_keyval_to_unicode(event->keyval);

  // For most modifier keys, GTK keeps track of the "pressed" state of the
  // modifier keys. Flutter uses this information to keep modifier keys from
  // being "stuck" when a key-up event is lost because it happens after the app
  // loses focus.
  //
  // For Lock keys (ShiftLock, CapsLock, NumLock), however, GTK keeps track of
  // the state of the locks themselves, not the "pressed" state of the key.
  //
  // Since Flutter expects the "pressed" state of the modifier keys, the lock
  // state for these keys is discarded here, and it is substituted for the
  // pressed state of the key.
  //
  // This code has the flaw that if a key event is missed due to the app losing
  // focus, then this state will still think the key is pressed when it isn't,
  // but that is no worse than for "regular" keys until we implement the
  // sync/cancel events on app focus changes.
  //
  // This is necessary to do here instead of in the framework because Flutter
  // does modifier key syncing in the framework, and will turn on/off these keys
  // as being "pressed" whenever the lock is on, which breaks a lot of
  // interactions (for example, if shift-lock is on, tab traversal is broken).

  // Remove lock states from state mask.
  guint state = event->state & ~(GDK_LOCK_MASK | GDK_MOD2_MASK);

  static bool shift_lock_pressed = FALSE;
  static bool caps_lock_pressed = FALSE;
  static bool num_lock_pressed = FALSE;
  switch (event->keyval) {
    case GDK_KEY_Num_Lock:
      num_lock_pressed = event->is_press;
      break;
    case GDK_KEY_Caps_Lock:
      caps_lock_pressed = event->is_press;
      break;
    case GDK_KEY_Shift_Lock:
      shift_lock_pressed = event->is_press;
      break;
  }

  // Add back in the state matching the actual pressed state of the lock keys,
  // not the lock states.
  state |= (shift_lock_pressed || caps_lock_pressed) ? GDK_LOCK_MASK : 0x0;
  state |= num_lock_pressed ? GDK_MOD2_MASK : 0x0;

  g_autoptr(FlValue) message = fl_value_new_map();
  fl_value_set_string_take(message, kTypeKey, fl_value_new_string(type));
  fl_value_set_string_take(message, kKeymapKey,
                           fl_value_new_string(kLinuxKeymap));
  fl_value_set_string_take(message, kScanCodeKey, fl_value_new_int(scan_code));
  fl_value_set_string_take(message, kToolkitKey,
                           fl_value_new_string(kGtkToolkit));
  fl_value_set_string_take(message, kKeyCodeKey,
                           fl_value_new_int(event->keyval));
  fl_value_set_string_take(message, kModifiersKey, fl_value_new_int(state));
  if (unicode_scarlar_values != 0) {
    fl_value_set_string_take(message, kUnicodeScalarValuesKey,
                             fl_value_new_int(unicode_scarlar_values));
  }

  FlKeyChannelUserData* data =
      fl_key_channel_user_data_new(self, callback, user_data);
  // Send the message off to the framework for handling (or not).
  fl_basic_message_channel_send(self->channel, message, nullptr,
                                handle_response, data);
}
