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

#include "flutter/shell/platform/common/cpp/text_input_model.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_method_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"

#include <gtk/gtk.h>

static constexpr char kChannelName[] = "flutter/textinput";

static constexpr char kSetClientMethod[] = "TextInput.setClient";
static constexpr char kShowMethod[] = "TextInput.show";
static constexpr char kSetEditingStateMethod[] = "TextInput.setEditingState";
static constexpr char kClearClientMethod[] = "TextInput.clearClient";
static constexpr char kHideMethod[] = "TextInput.hide";
static constexpr char kUpdateEditingStateMethod[] =
    "TextInputClient.updateEditingState";
static constexpr char kPerformActionMethod[] = "TextInputClient.performAction";

static constexpr char kInputActionKey[] = "inputAction";
static constexpr char kTextKey[] = "text";
static constexpr char kSelectionBaseKey[] = "selectionBase";
static constexpr char kSelectionExtentKey[] = "selectionExtent";
static constexpr char kSelectionAffinityKey[] = "selectionAffinity";
static constexpr char kSelectionIsDirectionalKey[] = "selectionIsDirectional";
static constexpr char kComposingBaseKey[] = "composingBase";
static constexpr char kComposingExtentKey[] = "composingExtent";

static constexpr char kTextAffinityDownstream[] = "TextAffinity.downstream";

static constexpr int64_t kClientIdUnset = -1;

struct _FlTextInputPlugin {
  GObject parent_instance;

  FlMethodChannel* channel;

  // Client ID provided by Flutter to report events with.
  int64_t client_id;

  // Input action to perform when enter pressed.
  gchar* input_action;

  // Input method.
  GtkIMContext* im_context;

  flutter::TextInputModel* text_model;
};

G_DEFINE_TYPE(FlTextInputPlugin, fl_text_input_plugin, G_TYPE_OBJECT)

// Completes method call and returns TRUE if the call was successful.
static gboolean finish_method(GObject* object,
                              GAsyncResult* result,
                              GError** error) {
  g_autoptr(FlMethodResponse) response = fl_method_channel_invoke_method_finish(
      FL_METHOD_CHANNEL(object), result, error);
  if (response == nullptr)
    return FALSE;
  return fl_method_response_get_result(response, error) != nullptr;
}

// Called when a response is received from TextInputClient.updateEditingState()
static void update_editing_state_response_cb(GObject* object,
                                             GAsyncResult* result,
                                             gpointer user_data) {
  g_autoptr(GError) error = nullptr;
  if (!finish_method(object, result, &error)) {
    g_warning("Failed to call %s: %s", kUpdateEditingStateMethod,
              error->message);
  }
}

// Informs Flutter of text input changes.
static void update_editing_state(FlTextInputPlugin* self) {
  g_autoptr(FlValue) args = fl_value_new_list();
  fl_value_append_take(args, fl_value_new_int(self->client_id));
  g_autoptr(FlValue) value = fl_value_new_map();

  fl_value_set_string_take(
      value, kTextKey,
      fl_value_new_string(self->text_model->GetText().c_str()));
  fl_value_set_string_take(
      value, kSelectionBaseKey,
      fl_value_new_int(self->text_model->selection_base()));
  fl_value_set_string_take(
      value, kSelectionExtentKey,
      fl_value_new_int(self->text_model->selection_extent()));

  // The following keys are not implemented and set to default values.
  fl_value_set_string_take(value, kSelectionAffinityKey,
                           fl_value_new_string(kTextAffinityDownstream));
  fl_value_set_string_take(value, kSelectionIsDirectionalKey,
                           fl_value_new_bool(FALSE));
  fl_value_set_string_take(value, kComposingBaseKey, fl_value_new_int(-1));
  fl_value_set_string_take(value, kComposingExtentKey, fl_value_new_int(-1));

  fl_value_append(args, value);

  fl_method_channel_invoke_method(self->channel, kUpdateEditingStateMethod,
                                  args, nullptr,
                                  update_editing_state_response_cb, self);
}

// Called when a response is received from TextInputClient.performAction()
static void perform_action_response_cb(GObject* object,
                                       GAsyncResult* result,
                                       gpointer user_data) {
  g_autoptr(GError) error = nullptr;
  if (!finish_method(object, result, &error))
    g_warning("Failed to call %s: %s", kPerformActionMethod, error->message);
}

// Inform Flutter that the input has been activated.
static void perform_action(FlTextInputPlugin* self) {
  g_return_if_fail(FL_IS_TEXT_INPUT_PLUGIN(self));
  g_return_if_fail(self->client_id != 0);
  g_return_if_fail(self->input_action != nullptr);

  g_autoptr(FlValue) args = fl_value_new_list();
  fl_value_append_take(args, fl_value_new_int(self->client_id));
  fl_value_append_take(args, fl_value_new_string(self->input_action));

  fl_method_channel_invoke_method(self->channel, kPerformActionMethod, args,
                                  nullptr, perform_action_response_cb, self);
}

// Signal handler for GtkIMContext::commit
static void im_commit_cb(FlTextInputPlugin* self, const gchar* text) {
  self->text_model->AddText(text);
  update_editing_state(self);
}

// Signal handler for GtkIMContext::retrieve-surrounding
static gboolean im_retrieve_surrounding_cb(FlTextInputPlugin* self) {
  auto text = self->text_model->GetText();
  size_t cursor_offset = self->text_model->GetCursorOffset();
  gtk_im_context_set_surrounding(self->im_context, text.c_str(), -1,
                                 cursor_offset);
  return TRUE;
}

// Signal handler for GtkIMContext::delete-surrounding
static gboolean im_delete_surrounding_cb(FlTextInputPlugin* self,
                                         gint offset,
                                         gint n_chars) {
  if (self->text_model->DeleteSurrounding(offset, n_chars))
    update_editing_state(self);
  return TRUE;
}

// Called when a method call is received from Flutter.
static void method_call_cb(FlMethodChannel* channel,
                           FlMethodCall* method_call,
                           gpointer user_data) {
  FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(user_data);

  const gchar* method = fl_method_call_get_name(method_call);
  FlValue* args = fl_method_call_get_args(method_call);

  if (strcmp(method, kSetClientMethod) == 0) {
    self->client_id = fl_value_get_int(fl_value_get_list_value(args, 0));
    FlValue* config_value = fl_value_get_list_value(args, 1);
    g_free(self->input_action);
    FlValue* input_action_value =
        fl_value_lookup_string(config_value, kInputActionKey);
    if (fl_value_get_type(input_action_value) == FL_VALUE_TYPE_STRING)
      self->input_action = g_strdup(fl_value_get_string(input_action_value));
    fl_method_call_respond_success(method_call, nullptr, nullptr);
  } else if (strcmp(method, kShowMethod) == 0) {
    gtk_im_context_focus_in(self->im_context);
    fl_method_call_respond_success(method_call, nullptr, nullptr);
  } else if (strcmp(method, kSetEditingStateMethod) == 0) {
    const gchar* text =
        fl_value_get_string(fl_value_lookup_string(args, kTextKey));
    int64_t selection_base =
        fl_value_get_int(fl_value_lookup_string(args, kSelectionBaseKey));
    int64_t selection_extent =
        fl_value_get_int(fl_value_lookup_string(args, kSelectionExtentKey));

    self->text_model->SetEditingState(selection_base, selection_extent, text);

    fl_method_call_respond_success(method_call, nullptr, nullptr);
  } else if (strcmp(method, kClearClientMethod) == 0) {
    self->client_id = kClientIdUnset;
    fl_method_call_respond_success(method_call, nullptr, nullptr);
  } else if (strcmp(method, kHideMethod) == 0) {
    gtk_im_context_focus_out(self->im_context);
    fl_method_call_respond_success(method_call, nullptr, nullptr);
  } else
    fl_method_call_respond_not_implemented(method_call, nullptr);
}

static void fl_text_input_plugin_dispose(GObject* object) {
  FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(object);

  g_clear_object(&self->channel);
  g_clear_pointer(&self->input_action, g_free);
  g_clear_object(&self->im_context);
  if (self->text_model != nullptr) {
    delete self->text_model;
    self->text_model = nullptr;
  }

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

static void fl_text_input_plugin_class_init(FlTextInputPluginClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_text_input_plugin_dispose;
}

static void fl_text_input_plugin_init(FlTextInputPlugin* self) {
  self->client_id = kClientIdUnset;
  self->im_context = gtk_im_multicontext_new();
  g_signal_connect_object(self->im_context, "commit", G_CALLBACK(im_commit_cb),
                          self, G_CONNECT_SWAPPED);
  g_signal_connect_object(self->im_context, "retrieve-surrounding",
                          G_CALLBACK(im_retrieve_surrounding_cb), self,
                          G_CONNECT_SWAPPED);
  g_signal_connect_object(self->im_context, "delete-surrounding",
                          G_CALLBACK(im_delete_surrounding_cb), self,
                          G_CONNECT_SWAPPED);
  self->text_model = new flutter::TextInputModel("", "");
}

FlTextInputPlugin* fl_text_input_plugin_new(FlBinaryMessenger* messenger) {
  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);

  FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(
      g_object_new(fl_text_input_plugin_get_type(), nullptr));

  g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
  self->channel =
      fl_method_channel_new(messenger, kChannelName, FL_METHOD_CODEC(codec));
  fl_method_channel_set_method_call_handler(self->channel, method_call_cb, self,
                                            nullptr);

  return self;
}

gboolean fl_text_input_plugin_filter_keypress(FlTextInputPlugin* self,
                                              GdkEventKey* event) {
  g_return_val_if_fail(FL_IS_TEXT_INPUT_PLUGIN(self), FALSE);
  if (gtk_im_context_filter_keypress(self->im_context, event))
    return TRUE;

  // Handle navigation keys.
  gboolean changed = FALSE;
  if (event->type == GDK_KEY_PRESS) {
    switch (event->keyval) {
      case GDK_KEY_BackSpace:
        changed = self->text_model->Backspace();
        break;
      case GDK_KEY_Delete:
      case GDK_KEY_KP_Delete:
        // Already handled inside Flutter.
        break;
      case GDK_KEY_End:
      case GDK_KEY_KP_End:
        changed = self->text_model->MoveCursorToEnd();
        break;
      case GDK_KEY_Return:
      case GDK_KEY_KP_Enter:
      case GDK_KEY_ISO_Enter:
        perform_action(self);
        break;
      case GDK_KEY_Home:
      case GDK_KEY_KP_Home:
        changed = self->text_model->MoveCursorToBeginning();
        break;
      case GDK_KEY_Left:
      case GDK_KEY_KP_Left:
        // Already handled inside Flutter.
        break;
      case GDK_KEY_Right:
      case GDK_KEY_KP_Right:
        // Already handled inside Flutter.
        break;
    }
  }

  if (changed)
    update_editing_state(self);

  return FALSE;
}
