// 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_accessible_text_field.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_message_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_value.h"

G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoContext, g_object_unref)
// PangoLayout g_autoptr macro weren't added until 1.49.4. Add them manually.
// https://gitlab.gnome.org/GNOME/pango/-/commit/0b84e14
#if !PANGO_VERSION_CHECK(1, 49, 4)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(PangoLayout, g_object_unref)
#endif

typedef bool (*FlTextBoundaryCallback)(const PangoLogAttr* attr);

struct _FlAccessibleTextField {
  FlAccessibleNode parent_instance;

  gint selection_base;
  gint selection_extent;
  GtkEntryBuffer* buffer;
  FlutterTextDirection text_direction;
};

static void fl_accessible_text_iface_init(AtkTextIface* iface);
static void fl_accessible_editable_text_iface_init(AtkEditableTextIface* iface);

G_DEFINE_TYPE_WITH_CODE(
    FlAccessibleTextField,
    fl_accessible_text_field,
    FL_TYPE_ACCESSIBLE_NODE,
    G_IMPLEMENT_INTERFACE(ATK_TYPE_TEXT, fl_accessible_text_iface_init)
        G_IMPLEMENT_INTERFACE(ATK_TYPE_EDITABLE_TEXT,
                              fl_accessible_editable_text_iface_init))

static gchar* get_substring(FlAccessibleTextField* self,
                            glong start,
                            glong end) {
  const gchar* value = gtk_entry_buffer_get_text(self->buffer);
  if (end == -1) {
    // g_utf8_substring() accepts -1 since 2.72
    end = g_utf8_strlen(value, -1);
  }
  return g_utf8_substring(value, start, end);
}

static PangoContext* get_pango_context(FlAccessibleTextField* self) {
  PangoFontMap* font_map = pango_cairo_font_map_get_default();
  PangoContext* context = pango_font_map_create_context(font_map);
  pango_context_set_base_dir(context,
                             self->text_direction == kFlutterTextDirectionRTL
                                 ? PANGO_DIRECTION_RTL
                                 : PANGO_DIRECTION_LTR);
  return context;
}

static PangoLayout* create_pango_layout(FlAccessibleTextField* self) {
  g_autoptr(PangoContext) context = get_pango_context(self);
  PangoLayout* layout = pango_layout_new(context);
  pango_layout_set_text(layout, gtk_entry_buffer_get_text(self->buffer), -1);
  return layout;
}

static gchar* get_string_at_offset(FlAccessibleTextField* self,
                                   gint start,
                                   gint end,
                                   FlTextBoundaryCallback is_start,
                                   FlTextBoundaryCallback is_end,
                                   gint* start_offset,
                                   gint* end_offset) {
  g_autoptr(PangoLayout) layout = create_pango_layout(self);

  gint n_attrs = 0;
  const PangoLogAttr* attrs =
      pango_layout_get_log_attrs_readonly(layout, &n_attrs);

  while (start > 0 && !is_start(&attrs[start])) {
    --start;
  }
  if (start_offset != nullptr) {
    *start_offset = start;
  }

  while (end < n_attrs && !is_end(&attrs[end])) {
    ++end;
  }
  if (end_offset != nullptr) {
    *end_offset = end;
  }

  return get_substring(self, start, end);
}

static gchar* get_char_at_offset(FlAccessibleTextField* self,
                                 gint offset,
                                 gint* start_offset,
                                 gint* end_offset) {
  return get_string_at_offset(
      self, offset, offset + 1,
      [](const PangoLogAttr* attr) -> bool { return attr->is_char_break; },
      [](const PangoLogAttr* attr) -> bool { return attr->is_char_break; },
      start_offset, end_offset);
}

static gchar* get_word_at_offset(FlAccessibleTextField* self,
                                 gint offset,
                                 gint* start_offset,
                                 gint* end_offset) {
  return get_string_at_offset(
      self, offset, offset,
      [](const PangoLogAttr* attr) -> bool { return attr->is_word_start; },
      [](const PangoLogAttr* attr) -> bool { return attr->is_word_end; },
      start_offset, end_offset);
}

static gchar* get_sentence_at_offset(FlAccessibleTextField* self,
                                     gint offset,
                                     gint* start_offset,
                                     gint* end_offset) {
  return get_string_at_offset(
      self, offset, offset,
      [](const PangoLogAttr* attr) -> bool { return attr->is_sentence_start; },
      [](const PangoLogAttr* attr) -> bool { return attr->is_sentence_end; },
      start_offset, end_offset);
}

static gchar* get_line_at_offset(FlAccessibleTextField* self,
                                 gint offset,
                                 gint* start_offset,
                                 gint* end_offset) {
  g_autoptr(PangoLayout) layout = create_pango_layout(self);

  GSList* lines = pango_layout_get_lines_readonly(layout);
  while (lines != nullptr) {
    PangoLayoutLine* line = static_cast<PangoLayoutLine*>(lines->data);
    if (offset >= line->start_index &&
        offset <= line->start_index + line->length) {
      if (start_offset != nullptr) {
        *start_offset = line->start_index;
      }
      if (end_offset != nullptr) {
        *end_offset = line->start_index + line->length;
      }
      return get_substring(self, line->start_index,
                           line->start_index + line->length);
    }
    lines = lines->next;
  }

  return nullptr;
}

static gchar* get_paragraph_at_offset(FlAccessibleTextField* self,
                                      gint offset,
                                      gint* start_offset,
                                      gint* end_offset) {
  g_autoptr(PangoLayout) layout = create_pango_layout(self);

  PangoLayoutLine* start = nullptr;
  PangoLayoutLine* end = nullptr;
  gint n_lines = pango_layout_get_line_count(layout);
  for (gint i = 0; i < n_lines; ++i) {
    PangoLayoutLine* line = pango_layout_get_line(layout, i);
    if (line->is_paragraph_start) {
      end = line;
    }
    if (start != nullptr && end != nullptr && offset >= start->start_index &&
        offset <= end->start_index + end->length) {
      if (start_offset != nullptr) {
        *start_offset = start->start_index;
      }
      if (end_offset != nullptr) {
        *end_offset = end->start_index + end->length;
      }
      return get_substring(self, start->start_index,
                           end->start_index + end->length);
    }
    if (line->is_paragraph_start) {
      start = line;
    }
  }

  return nullptr;
}

static void perform_set_text_action(FlAccessibleTextField* self,
                                    const char* text) {
  g_autoptr(FlValue) value = fl_value_new_string(text);
  g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new();
  g_autoptr(GBytes) message =
      fl_message_codec_encode_message(FL_MESSAGE_CODEC(codec), value, nullptr);

  fl_accessible_node_perform_action(FL_ACCESSIBLE_NODE(self),
                                    kFlutterSemanticsActionSetText, message);
}

static void perform_set_selection_action(FlAccessibleTextField* self,
                                         gint base,
                                         gint extent) {
  g_autoptr(FlValue) value = fl_value_new_map();
  fl_value_set_string_take(value, "base", fl_value_new_int(base));
  fl_value_set_string_take(value, "extent", fl_value_new_int(extent));

  g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new();
  g_autoptr(GBytes) message =
      fl_message_codec_encode_message(FL_MESSAGE_CODEC(codec), value, nullptr);

  fl_accessible_node_perform_action(
      FL_ACCESSIBLE_NODE(self), kFlutterSemanticsActionSetSelection, message);
}

// Implements GObject::dispose.
static void fl_accessible_text_field_dispose(GObject* object) {
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(object);

  g_clear_object(&self->buffer);

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

// Implements FlAccessibleNode::set_value.
static void fl_accessible_text_field_set_value(FlAccessibleNode* node,
                                               const gchar* value) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(node));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(node);

  if (g_strcmp0(gtk_entry_buffer_get_text(self->buffer), value) == 0) {
    return;
  }

  gtk_entry_buffer_set_text(self->buffer, value, -1);
}

// Implements FlAccessibleNode::set_text_selection.
static void fl_accessible_text_field_set_text_selection(FlAccessibleNode* node,
                                                        gint base,
                                                        gint extent) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(node));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(node);

  gboolean caret_moved = extent != self->selection_extent;
  gboolean has_selection = base != extent;
  gboolean had_selection = self->selection_base != self->selection_extent;
  gboolean selection_changed = (has_selection || had_selection) &&
                               (caret_moved || base != self->selection_base);

  self->selection_base = base;
  self->selection_extent = extent;

  if (selection_changed) {
    g_signal_emit_by_name(self, "text-selection-changed", nullptr);
  }

  if (caret_moved) {
    g_signal_emit_by_name(self, "text-caret-moved", extent, nullptr);
  }
}

// Implements FlAccessibleNode::set_text_direction.
static void fl_accessible_text_field_set_text_direction(
    FlAccessibleNode* node,
    FlutterTextDirection direction) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(node));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(node);

  self->text_direction = direction;
}

// Overrides FlAccessibleNode::perform_action.
void fl_accessible_text_field_perform_action(FlAccessibleNode* self,
                                             FlutterSemanticsAction action,
                                             GBytes* data) {
  FlAccessibleNodeClass* parent_class =
      FL_ACCESSIBLE_NODE_CLASS(fl_accessible_text_field_parent_class);

  switch (action) {
    case kFlutterSemanticsActionMoveCursorForwardByCharacter:
    case kFlutterSemanticsActionMoveCursorBackwardByCharacter:
    case kFlutterSemanticsActionMoveCursorForwardByWord:
    case kFlutterSemanticsActionMoveCursorBackwardByWord: {
      // These actions require a boolean argument that indicates whether the
      // selection should be extended or collapsed when moving the cursor.
      g_autoptr(FlValue) extend_selection = fl_value_new_bool(false);
      g_autoptr(FlStandardMessageCodec) codec = fl_standard_message_codec_new();
      g_autoptr(GBytes) message = fl_message_codec_encode_message(
          FL_MESSAGE_CODEC(codec), extend_selection, nullptr);
      parent_class->perform_action(self, action, message);
      break;
    }
    default:
      parent_class->perform_action(self, action, data);
      break;
  }
}

// Implements AtkText::get_character_count.
static gint fl_accessible_text_field_get_character_count(AtkText* text) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), 0);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  return gtk_entry_buffer_get_length(self->buffer);
}

// Implements AtkText::get_text.
static gchar* fl_accessible_text_field_get_text(AtkText* text,
                                                gint start_offset,
                                                gint end_offset) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), nullptr);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  return get_substring(self, start_offset, end_offset);
}

// Implements AtkText::get_string_at_offset.
static gchar* fl_accessible_text_field_get_string_at_offset(
    AtkText* text,
    gint offset,
    AtkTextGranularity granularity,
    gint* start_offset,
    gint* end_offset) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), nullptr);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  switch (granularity) {
    case ATK_TEXT_GRANULARITY_CHAR:
      return get_char_at_offset(self, offset, start_offset, end_offset);
    case ATK_TEXT_GRANULARITY_WORD:
      return get_word_at_offset(self, offset, start_offset, end_offset);
    case ATK_TEXT_GRANULARITY_SENTENCE:
      return get_sentence_at_offset(self, offset, start_offset, end_offset);
    case ATK_TEXT_GRANULARITY_LINE:
      return get_line_at_offset(self, offset, start_offset, end_offset);
    case ATK_TEXT_GRANULARITY_PARAGRAPH:
      return get_paragraph_at_offset(self, offset, start_offset, end_offset);
    default:
      return nullptr;
  }
}

// Implements AtkText::get_text_at_offset (deprecated but still commonly used).
static gchar* fl_accessible_text_field_get_text_at_offset(
    AtkText* text,
    gint offset,
    AtkTextBoundary boundary_type,
    gint* start_offset,
    gint* end_offset) {
  switch (boundary_type) {
    case ATK_TEXT_BOUNDARY_CHAR:
      return fl_accessible_text_field_get_string_at_offset(
          text, offset, ATK_TEXT_GRANULARITY_CHAR, start_offset, end_offset);
      break;
    case ATK_TEXT_BOUNDARY_WORD_START:
    case ATK_TEXT_BOUNDARY_WORD_END:
      return fl_accessible_text_field_get_string_at_offset(
          text, offset, ATK_TEXT_GRANULARITY_WORD, start_offset, end_offset);
      break;
    case ATK_TEXT_BOUNDARY_SENTENCE_START:
    case ATK_TEXT_BOUNDARY_SENTENCE_END:
      return fl_accessible_text_field_get_string_at_offset(
          text, offset, ATK_TEXT_GRANULARITY_SENTENCE, start_offset,
          end_offset);
      break;
    case ATK_TEXT_BOUNDARY_LINE_START:
    case ATK_TEXT_BOUNDARY_LINE_END:
      return fl_accessible_text_field_get_string_at_offset(
          text, offset, ATK_TEXT_GRANULARITY_LINE, start_offset, end_offset);
      break;
    default:
      return nullptr;
  }
}

// Implements AtkText::get_caret_offset.
static gint fl_accessible_text_field_get_caret_offset(AtkText* text) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), -1);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  return self->selection_extent;
}

// Implements AtkText::set_caret_offset.
static gboolean fl_accessible_text_field_set_caret_offset(AtkText* text,
                                                          gint offset) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), false);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  perform_set_selection_action(self, offset, offset);
  return true;
}

// Implements AtkText::get_n_selections.
static gint fl_accessible_text_field_get_n_selections(AtkText* text) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), 0);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  if (self->selection_base == self->selection_extent) {
    return 0;
  }

  return 1;
}

// Implements AtkText::get_selection.
static gchar* fl_accessible_text_field_get_selection(AtkText* text,
                                                     gint selection_num,
                                                     gint* start_offset,
                                                     gint* end_offset) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), nullptr);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  if (selection_num != 0 || self->selection_base == self->selection_extent) {
    return nullptr;
  }

  gint start = MIN(self->selection_base, self->selection_extent);
  gint end = MAX(self->selection_base, self->selection_extent);

  if (start_offset != nullptr) {
    *start_offset = start;
  }
  if (end_offset != nullptr) {
    *end_offset = end;
  }

  return get_substring(self, start, end);
}

// Implements AtkText::add_selection.
static gboolean fl_accessible_text_field_add_selection(AtkText* text,
                                                       gint start_offset,
                                                       gint end_offset) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), false);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  if (self->selection_base != self->selection_extent) {
    return false;
  }

  perform_set_selection_action(self, start_offset, end_offset);
  return true;
}

// Implements AtkText::remove_selection.
static gboolean fl_accessible_text_field_remove_selection(AtkText* text,
                                                          gint selection_num) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), false);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  if (selection_num != 0 || self->selection_base == self->selection_extent) {
    return false;
  }

  perform_set_selection_action(self, self->selection_extent,
                               self->selection_extent);
  return true;
}

// Implements AtkText::set_selection.
static gboolean fl_accessible_text_field_set_selection(AtkText* text,
                                                       gint selection_num,
                                                       gint start_offset,
                                                       gint end_offset) {
  g_return_val_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(text), false);
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(text);

  if (selection_num != 0) {
    return false;
  }

  perform_set_selection_action(self, start_offset, end_offset);
  return true;
}

// Implements AtkEditableText::set_text_contents.
static void fl_accessible_text_field_set_text_contents(
    AtkEditableText* editable_text,
    const gchar* string) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(editable_text));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(editable_text);

  perform_set_text_action(self, string);
}

// Implements AtkEditableText::insert_text.
static void fl_accessible_text_field_insert_text(AtkEditableText* editable_text,
                                                 const gchar* string,
                                                 gint length,
                                                 gint* position) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(editable_text));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(editable_text);

  *position +=
      gtk_entry_buffer_insert_text(self->buffer, *position, string, length);

  perform_set_text_action(self, gtk_entry_buffer_get_text(self->buffer));
  perform_set_selection_action(self, *position, *position);
}

// Implements AtkEditableText::delete_text.
static void fl_accessible_node_delete_text(AtkEditableText* editable_text,
                                           gint start_pos,
                                           gint end_pos) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(editable_text));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(editable_text);

  gtk_entry_buffer_delete_text(self->buffer, start_pos, end_pos - start_pos);

  perform_set_text_action(self, gtk_entry_buffer_get_text(self->buffer));
  perform_set_selection_action(self, start_pos, start_pos);
}

// Implement AtkEditableText::copy_text.
static void fl_accessible_text_field_copy_text(AtkEditableText* editable_text,
                                               gint start_pos,
                                               gint end_pos) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(editable_text));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(editable_text);

  perform_set_selection_action(self, start_pos, end_pos);

  fl_accessible_node_perform_action(FL_ACCESSIBLE_NODE(editable_text),
                                    kFlutterSemanticsActionCopy, nullptr);
}

// Implements AtkEditableText::cut_text.
static void fl_accessible_text_field_cut_text(AtkEditableText* editable_text,
                                              gint start_pos,
                                              gint end_pos) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(editable_text));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(editable_text);

  perform_set_selection_action(self, start_pos, end_pos);

  fl_accessible_node_perform_action(FL_ACCESSIBLE_NODE(editable_text),
                                    kFlutterSemanticsActionCut, nullptr);
}

// Implements AtkEditableText::paste_text.
static void fl_accessible_text_field_paste_text(AtkEditableText* editable_text,
                                                gint position) {
  g_return_if_fail(FL_IS_ACCESSIBLE_TEXT_FIELD(editable_text));
  FlAccessibleTextField* self = FL_ACCESSIBLE_TEXT_FIELD(editable_text);

  perform_set_selection_action(self, position, position);

  fl_accessible_node_perform_action(FL_ACCESSIBLE_NODE(editable_text),
                                    kFlutterSemanticsActionPaste, nullptr);
}

static void fl_accessible_text_field_class_init(
    FlAccessibleTextFieldClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_accessible_text_field_dispose;
  FL_ACCESSIBLE_NODE_CLASS(klass)->set_value =
      fl_accessible_text_field_set_value;
  FL_ACCESSIBLE_NODE_CLASS(klass)->set_text_selection =
      fl_accessible_text_field_set_text_selection;
  FL_ACCESSIBLE_NODE_CLASS(klass)->set_text_direction =
      fl_accessible_text_field_set_text_direction;
  FL_ACCESSIBLE_NODE_CLASS(klass)->perform_action =
      fl_accessible_text_field_perform_action;
}

static void fl_accessible_text_iface_init(AtkTextIface* iface) {
  iface->get_character_count = fl_accessible_text_field_get_character_count;
  iface->get_text = fl_accessible_text_field_get_text;
  iface->get_text_at_offset = fl_accessible_text_field_get_text_at_offset;
  iface->get_string_at_offset = fl_accessible_text_field_get_string_at_offset;

  iface->get_caret_offset = fl_accessible_text_field_get_caret_offset;
  iface->set_caret_offset = fl_accessible_text_field_set_caret_offset;

  iface->get_n_selections = fl_accessible_text_field_get_n_selections;
  iface->get_selection = fl_accessible_text_field_get_selection;
  iface->add_selection = fl_accessible_text_field_add_selection;
  iface->remove_selection = fl_accessible_text_field_remove_selection;
  iface->set_selection = fl_accessible_text_field_set_selection;
}

static void fl_accessible_editable_text_iface_init(
    AtkEditableTextIface* iface) {
  iface->set_text_contents = fl_accessible_text_field_set_text_contents;
  iface->insert_text = fl_accessible_text_field_insert_text;
  iface->delete_text = fl_accessible_node_delete_text;

  iface->copy_text = fl_accessible_text_field_copy_text;
  iface->cut_text = fl_accessible_text_field_cut_text;
  iface->paste_text = fl_accessible_text_field_paste_text;
}

static void fl_accessible_text_field_init(FlAccessibleTextField* self) {
  self->selection_base = -1;
  self->selection_extent = -1;

  self->buffer = gtk_entry_buffer_new("", 0);

  g_signal_connect_object(
      self->buffer, "inserted-text",
      G_CALLBACK(+[](FlAccessibleTextField* self, guint position, gchar* chars,
                     guint n_chars) {
        g_signal_emit_by_name(self, "text-insert", position, n_chars, chars,
                              nullptr);
      }),
      self, G_CONNECT_SWAPPED);

  g_signal_connect_object(self->buffer, "deleted-text",
                          G_CALLBACK(+[](FlAccessibleTextField* self,
                                         guint position, guint n_chars) {
                            g_autofree gchar* chars = atk_text_get_text(
                                ATK_TEXT(self), position, position + n_chars);
                            g_signal_emit_by_name(self, "text-remove", position,
                                                  n_chars, chars, nullptr);
                          }),
                          self, G_CONNECT_SWAPPED);
}

FlAccessibleNode* fl_accessible_text_field_new(FlEngine* engine, int32_t id) {
  return FL_ACCESSIBLE_NODE(g_object_new(fl_accessible_text_field_get_type(),
                                         "engine", engine, "id", id, nullptr));
}
