// 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_node.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"

// Maps Flutter semantics flags to ATK flags.
static struct {
  AtkStateType state;
  FlutterSemanticsFlag flag;
  gboolean invert;
} flag_mapping[] = {
    {ATK_STATE_SHOWING, kFlutterSemanticsFlagIsObscured, TRUE},
    {ATK_STATE_VISIBLE, kFlutterSemanticsFlagIsHidden, TRUE},
    {ATK_STATE_CHECKABLE, kFlutterSemanticsFlagHasCheckedState, FALSE},
    {ATK_STATE_FOCUSABLE, kFlutterSemanticsFlagIsFocusable, FALSE},
    {ATK_STATE_FOCUSED, kFlutterSemanticsFlagIsFocused, FALSE},
    {ATK_STATE_CHECKED,
     static_cast<FlutterSemanticsFlag>(kFlutterSemanticsFlagIsChecked |
                                       kFlutterSemanticsFlagIsToggled),
     FALSE},
    {ATK_STATE_SELECTED, kFlutterSemanticsFlagIsSelected, FALSE},
    {ATK_STATE_ENABLED, kFlutterSemanticsFlagIsEnabled, FALSE},
    {ATK_STATE_SENSITIVE, kFlutterSemanticsFlagIsEnabled, FALSE},
    {ATK_STATE_READ_ONLY, kFlutterSemanticsFlagIsReadOnly, FALSE},
    {ATK_STATE_INVALID, static_cast<FlutterSemanticsFlag>(0), FALSE},
};

// Maps Flutter semantics actions to ATK actions.
typedef struct {
  FlutterSemanticsAction action;
  const gchar* name;
} ActionData;
static ActionData action_mapping[] = {
    {kFlutterSemanticsActionTap, "Tap"},
    {kFlutterSemanticsActionLongPress, "LongPress"},
    {kFlutterSemanticsActionScrollLeft, "ScrollLeft"},
    {kFlutterSemanticsActionScrollRight, "ScrollRight"},
    {kFlutterSemanticsActionScrollUp, "ScrollUp"},
    {kFlutterSemanticsActionScrollDown, "ScrollDown"},
    {kFlutterSemanticsActionIncrease, "Increase"},
    {kFlutterSemanticsActionDecrease, "Decrease"},
    {kFlutterSemanticsActionShowOnScreen, "ShowOnScreen"},
    {kFlutterSemanticsActionMoveCursorForwardByCharacter,
     "MoveCursorForwardByCharacter"},
    {kFlutterSemanticsActionMoveCursorBackwardByCharacter,
     "MoveCursorBackwardByCharacter"},
    {kFlutterSemanticsActionSetSelection, "SetSelection"},
    {kFlutterSemanticsActionCopy, "Copy"},
    {kFlutterSemanticsActionCut, "Cut"},
    {kFlutterSemanticsActionPaste, "Paste"},
    {kFlutterSemanticsActionDidGainAccessibilityFocus,
     "DidGainAccessibilityFocus"},
    {kFlutterSemanticsActionDidLoseAccessibilityFocus,
     "DidLoseAccessibilityFocus"},
    {kFlutterSemanticsActionCustomAction, "CustomAction"},
    {kFlutterSemanticsActionDismiss, "Dismiss"},
    {kFlutterSemanticsActionMoveCursorForwardByWord, "MoveCursorForwardByWord"},
    {kFlutterSemanticsActionMoveCursorBackwardByWord,
     "MoveCursorBackwardByWord"},
    {static_cast<FlutterSemanticsAction>(0), nullptr}};

struct _FlAccessibleNode {
  AtkObject parent_instance;

  // Weak reference to the engine this node is created for.
  FlEngine* engine;

  // Weak reference to the parent node of this one or %NULL.
  AtkObject* parent;

  int32_t id;
  gchar* name;
  gint index;
  gint x, y, width, height;
  GPtrArray* actions;
  gsize actions_length;
  GPtrArray* children;
  FlutterSemanticsFlag flags;
};

static void fl_accessible_node_component_interface_init(
    AtkComponentIface* iface);
static void fl_accessible_node_action_interface_init(AtkActionIface* iface);
static void fl_accessible_node_text_interface_init(AtkTextIface* iface);

G_DEFINE_TYPE_WITH_CODE(
    FlAccessibleNode,
    fl_accessible_node,
    ATK_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE(ATK_TYPE_COMPONENT,
                          fl_accessible_node_component_interface_init)
        G_IMPLEMENT_INTERFACE(ATK_TYPE_ACTION,
                              fl_accessible_node_action_interface_init)
            G_IMPLEMENT_INTERFACE(ATK_TYPE_TEXT,
                                  fl_accessible_node_text_interface_init))

// Returns TRUE if [flag] has changed between [old_flags] and [flags].
static gboolean flag_is_changed(FlutterSemanticsFlag old_flags,
                                FlutterSemanticsFlag flags,
                                FlutterSemanticsFlag flag) {
  return (old_flags & flag) != (flags & flag);
}

// Returns TRUE if [flag] is set in [flags].
static gboolean has_flag(FlutterSemanticsFlag flags,
                         FlutterSemanticsFlag flag) {
  return (flags & flag) != 0;
}

// Returns TRUE if [action] is set in [actions].
static gboolean has_action(FlutterSemanticsAction actions,
                           FlutterSemanticsAction action) {
  return (actions & action) != 0;
}

// Gets the nth action.
static ActionData* get_action(FlAccessibleNode* self, gint index) {
  if (index < 0 || static_cast<guint>(index) >= self->actions->len) {
    return nullptr;
  }
  return static_cast<ActionData*>(g_ptr_array_index(self->actions, index));
}

// Checks if [object] is in [children].
static gboolean has_child(GPtrArray* children, AtkObject* object) {
  for (guint i = 0; i < children->len; i++) {
    if (g_ptr_array_index(children, i) == object) {
      return TRUE;
    }
  }

  return FALSE;
}

static void fl_accessible_node_dispose(GObject* object) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(object);

  if (self->engine != nullptr) {
    g_object_remove_weak_pointer(G_OBJECT(self),
                                 reinterpret_cast<gpointer*>(&(self->engine)));
    self->engine = nullptr;
  }
  if (self->parent != nullptr) {
    g_object_remove_weak_pointer(G_OBJECT(self),
                                 reinterpret_cast<gpointer*>(&(self->parent)));
    self->parent = nullptr;
  }
  g_clear_pointer(&self->name, g_free);
  g_clear_pointer(&self->actions, g_ptr_array_unref);
  g_clear_pointer(&self->children, g_ptr_array_unref);

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

// Implements AtkObject::get_name.
static const gchar* fl_accessible_node_get_name(AtkObject* accessible) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(accessible);
  return self->name;
}

// Implements AtkObject::get_parent.
static AtkObject* fl_accessible_node_get_parent(AtkObject* accessible) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(accessible);
  return self->parent;
}

// Implements AtkObject::get_index_in_parent.
static gint fl_accessible_node_get_index_in_parent(AtkObject* accessible) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(accessible);
  return self->index;
}

// Implements AtkObject::get_n_children.
static gint fl_accessible_node_get_n_children(AtkObject* accessible) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(accessible);
  return self->children->len;
}

// Implements AtkObject::ref_child.
static AtkObject* fl_accessible_node_ref_child(AtkObject* accessible, gint i) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(accessible);

  if (i < 0 || static_cast<guint>(i) >= self->children->len) {
    return nullptr;
  }

  return ATK_OBJECT(g_object_ref(g_ptr_array_index(self->children, i)));
}

// Implements AtkObject::get_role.
static AtkRole fl_accessible_node_get_role(AtkObject* accessible) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(accessible);
  if ((self->flags & kFlutterSemanticsFlagIsButton) != 0) {
    return ATK_ROLE_PUSH_BUTTON;
  }
  if ((self->flags & kFlutterSemanticsFlagIsInMutuallyExclusiveGroup) != 0 &&
      (self->flags & kFlutterSemanticsFlagHasCheckedState) != 0) {
    return ATK_ROLE_RADIO_BUTTON;
  }
  if ((self->flags & kFlutterSemanticsFlagHasCheckedState) != 0) {
    return ATK_ROLE_CHECK_BOX;
  }
  if ((self->flags & kFlutterSemanticsFlagHasToggledState) != 0) {
    return ATK_ROLE_TOGGLE_BUTTON;
  }
  if ((self->flags & kFlutterSemanticsFlagIsSlider) != 0) {
    return ATK_ROLE_SLIDER;
  }
  if ((self->flags & kFlutterSemanticsFlagIsTextField) != 0 &&
      (self->flags & kFlutterSemanticsFlagIsObscured) != 0) {
    return ATK_ROLE_PASSWORD_TEXT;
  }
  if ((self->flags & kFlutterSemanticsFlagIsTextField) != 0) {
    return ATK_ROLE_TEXT;
  }
  if ((self->flags & kFlutterSemanticsFlagIsHeader) != 0) {
    return ATK_ROLE_HEADER;
  }
  if ((self->flags & kFlutterSemanticsFlagIsLink) != 0) {
    return ATK_ROLE_LINK;
  }
  if ((self->flags & kFlutterSemanticsFlagIsImage) != 0) {
    return ATK_ROLE_IMAGE;
  }

  return ATK_ROLE_PANEL;
}

// Implements AtkObject::ref_state_set.
static AtkStateSet* fl_accessible_node_ref_state_set(AtkObject* accessible) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(accessible);

  AtkStateSet* state_set = atk_state_set_new();

  for (int i = 0; flag_mapping[i].state != ATK_STATE_INVALID; i++) {
    gboolean enabled = has_flag(self->flags, flag_mapping[i].flag);
    if (flag_mapping[i].invert) {
      enabled = !enabled;
    }
    if (enabled) {
      atk_state_set_add_state(state_set, flag_mapping[i].state);
    }
  }

  return state_set;
}

// Implements AtkComponent::get_extents.
static void fl_accessible_node_get_extents(AtkComponent* component,
                                           gint* x,
                                           gint* y,
                                           gint* width,
                                           gint* height,
                                           AtkCoordType coord_type) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(component);

  *x = 0;
  *y = 0;
  if (self->parent != nullptr) {
    atk_component_get_extents(ATK_COMPONENT(self->parent), x, y, nullptr,
                              nullptr, coord_type);
  }

  *x += self->x;
  *y += self->y;
  *width = self->width;
  *height = self->height;
}

// Implements AtkComponent::get_layer.
static AtkLayer fl_accessible_node_get_layer(AtkComponent* component) {
  return ATK_LAYER_WIDGET;
}

// Implements AtkAction::do_action.
static gboolean fl_accessible_node_do_action(AtkAction* action, gint i) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(action);

  if (self->engine == nullptr) {
    return FALSE;
  }

  ActionData* data = get_action(self, i);
  if (data == nullptr) {
    return FALSE;
  }

  fl_engine_dispatch_semantics_action(self->engine, self->id, data->action,
                                      nullptr);
  return TRUE;
}

// Implements AtkAction::get_n_actions.
static gint fl_accessible_node_get_n_actions(AtkAction* action) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(action);
  return self->actions->len;
}

// Implements AtkAction::get_name.
static const gchar* fl_accessible_node_get_name(AtkAction* action, gint i) {
  FlAccessibleNode* self = FL_ACCESSIBLE_NODE(action);

  ActionData* data = get_action(self, i);
  if (data == nullptr) {
    return nullptr;
  }

  return data->name;
}

// Implements AtkText::get_text.
static gchar* fl_accessible_node_get_text(AtkText* text,
                                          gint start_offset,
                                          gint end_offset) {
  return nullptr;
}

static void fl_accessible_node_class_init(FlAccessibleNodeClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_accessible_node_dispose;
  ATK_OBJECT_CLASS(klass)->get_name = fl_accessible_node_get_name;
  ATK_OBJECT_CLASS(klass)->get_parent = fl_accessible_node_get_parent;
  ATK_OBJECT_CLASS(klass)->get_index_in_parent =
      fl_accessible_node_get_index_in_parent;
  ATK_OBJECT_CLASS(klass)->get_n_children = fl_accessible_node_get_n_children;
  ATK_OBJECT_CLASS(klass)->ref_child = fl_accessible_node_ref_child;
  ATK_OBJECT_CLASS(klass)->get_role = fl_accessible_node_get_role;
  ATK_OBJECT_CLASS(klass)->ref_state_set = fl_accessible_node_ref_state_set;
}

static void fl_accessible_node_component_interface_init(
    AtkComponentIface* iface) {
  iface->get_extents = fl_accessible_node_get_extents;
  iface->get_layer = fl_accessible_node_get_layer;
}

static void fl_accessible_node_action_interface_init(AtkActionIface* iface) {
  iface->do_action = fl_accessible_node_do_action;
  iface->get_n_actions = fl_accessible_node_get_n_actions;
  iface->get_name = fl_accessible_node_get_name;
}

static void fl_accessible_node_text_interface_init(AtkTextIface* iface) {
  iface->get_text = fl_accessible_node_get_text;
}

static void fl_accessible_node_init(FlAccessibleNode* self) {
  self->actions = g_ptr_array_new();
  self->children = g_ptr_array_new_with_free_func(g_object_unref);
}

FlAccessibleNode* fl_accessible_node_new(FlEngine* engine, int32_t id) {
  FlAccessibleNode* self =
      FL_ACCESSIBLE_NODE(g_object_new(fl_accessible_node_get_type(), nullptr));
  self->engine = engine;
  g_object_add_weak_pointer(G_OBJECT(self),
                            reinterpret_cast<gpointer*>(&(self->engine)));
  self->id = id;
  return self;
}

void fl_accessible_node_set_parent(FlAccessibleNode* self,
                                   AtkObject* parent,
                                   gint index) {
  g_return_if_fail(FL_IS_ACCESSIBLE_NODE(self));
  self->parent = parent;
  self->index = index;
  g_object_add_weak_pointer(G_OBJECT(self),
                            reinterpret_cast<gpointer*>(&(self->parent)));
}

void fl_accessible_node_set_children(FlAccessibleNode* self,
                                     GPtrArray* children) {
  g_return_if_fail(FL_IS_ACCESSIBLE_NODE(self));

  // Remove nodes that are no longer required.
  for (guint i = 0; i < self->children->len;) {
    AtkObject* object = ATK_OBJECT(g_ptr_array_index(self->children, i));
    if (has_child(children, object)) {
      i++;
    } else {
      g_signal_emit_by_name(self, "children-changed::remove", i, object,
                            nullptr);
      g_ptr_array_remove_index(self->children, i);
    }
  }

  // Add new nodes.
  for (guint i = 0; i < children->len; i++) {
    AtkObject* object = ATK_OBJECT(g_ptr_array_index(children, i));
    if (!has_child(self->children, object)) {
      g_ptr_array_add(self->children, g_object_ref(object));
      g_signal_emit_by_name(self, "children-changed::add", i, object, nullptr);
    }
  }
}

void fl_accessible_node_set_name(FlAccessibleNode* self, const gchar* name) {
  g_return_if_fail(FL_IS_ACCESSIBLE_NODE(self));
  g_free(self->name);
  self->name = g_strdup(name);
}

void fl_accessible_node_set_extents(FlAccessibleNode* self,
                                    gint x,
                                    gint y,
                                    gint width,
                                    gint height) {
  g_return_if_fail(FL_IS_ACCESSIBLE_NODE(self));
  self->x = x;
  self->y = y;
  self->width = width;
  self->height = height;
}

void fl_accessible_node_set_flags(FlAccessibleNode* self,
                                  FlutterSemanticsFlag flags) {
  g_return_if_fail(FL_IS_ACCESSIBLE_NODE(self));

  FlutterSemanticsFlag old_flags = self->flags;
  self->flags = flags;

  for (int i = 0; flag_mapping[i].state != ATK_STATE_INVALID; i++) {
    if (flag_is_changed(old_flags, flags, flag_mapping[i].flag)) {
      gboolean enabled = has_flag(flags, flag_mapping[i].flag);
      if (flag_mapping[i].invert) {
        enabled = !enabled;
      }

      atk_object_notify_state_change(ATK_OBJECT(self), flag_mapping[i].state,
                                     enabled);
    }
  }
}

void fl_accessible_node_set_actions(FlAccessibleNode* self,
                                    FlutterSemanticsAction actions) {
  g_return_if_fail(FL_IS_ACCESSIBLE_NODE(self));

  // NOTE(robert-ancell): It appears that AtkAction doesn't have a method of
  // notifying that actions have changed, and even if it did an ATK client
  // might access the old IDs before checking for new ones. Keep an eye
  // out for a case where Flutter changes the actions on an item and see
  // if we can resolve this in another way.
  g_ptr_array_remove_range(self->actions, 0, self->actions->len);
  for (int i = 0; action_mapping[i].name != nullptr; i++) {
    if (has_action(actions, action_mapping[i].action)) {
      g_ptr_array_add(self->actions, &action_mapping[i]);
    }
  }
}
