// Copyright 2015 The Chromium 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 "ui/accessibility/platform/test_ax_node_wrapper.h"

#include <map>
#include <utility>

#include "base/numerics/ranges.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_action_data.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_table_info.h"
#include "ui/accessibility/ax_tree_observer.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace ui {

namespace {

// A global map from AXNodes to TestAXNodeWrappers.
std::map<AXNode::AXID, TestAXNodeWrapper*> g_node_id_to_wrapper_map;

// A global coordinate offset.
gfx::Vector2d g_offset;

// A global scale factor.
float g_scale_factor = 1.0;

// A global map that stores which node is focused on a determined tree.
//   - If a tree has no node being focused, there shouldn't be any entry on the
//     map associated with such tree, i.e. a pair {tree, nullptr} is invalid.
//   - For testing purposes, assume there is a single node being focused in the
//     entire tree and if such node is deleted, focus is completely lost.
std::map<AXTree*, AXNode*> g_focused_node_in_tree;

// A global indicating the last node which ShowContextMenu was called from.
AXNode* g_node_from_last_show_context_menu;

// A global indicating the last node which accessibility perform action
// default action was called from.
AXNode* g_node_from_last_default_action;

// A global indicating that AXPlatformNodeDelegate objects are web content.
bool g_is_web_content = false;

// A map of hit test results - a map from source node ID to destination node
// ID.
std::map<AXNode::AXID, AXNode::AXID> g_hit_test_result;

// A simple implementation of AXTreeObserver to catch when AXNodes are
// deleted so we can delete their wrappers.
class TestAXTreeObserver : public AXTreeObserver {
 private:
  void OnNodeDeleted(AXTree* tree, int32_t node_id) override {
    const auto iter = g_node_id_to_wrapper_map.find(node_id);
    if (iter != g_node_id_to_wrapper_map.end()) {
      TestAXNodeWrapper* wrapper = iter->second;
      delete wrapper;
      g_node_id_to_wrapper_map.erase(node_id);
    }
  }
};

TestAXTreeObserver g_ax_tree_observer;

}  // namespace

// static
TestAXNodeWrapper* TestAXNodeWrapper::GetOrCreate(AXTree* tree, AXNode* node) {
  if (!tree || !node)
    return nullptr;

  if (!tree->HasObserver(&g_ax_tree_observer))
    tree->AddObserver(&g_ax_tree_observer);
  auto iter = g_node_id_to_wrapper_map.find(node->id());
  if (iter != g_node_id_to_wrapper_map.end())
    return iter->second;
  TestAXNodeWrapper* wrapper = new TestAXNodeWrapper(tree, node);
  g_node_id_to_wrapper_map[node->id()] = wrapper;
  return wrapper;
}

// static
void TestAXNodeWrapper::SetGlobalCoordinateOffset(const gfx::Vector2d& offset) {
  g_offset = offset;
}

// static
const AXNode* TestAXNodeWrapper::GetNodeFromLastShowContextMenu() {
  return g_node_from_last_show_context_menu;
}

// static
const AXNode* TestAXNodeWrapper::GetNodeFromLastDefaultAction() {
  return g_node_from_last_default_action;
}

// static
void TestAXNodeWrapper::SetNodeFromLastDefaultAction(AXNode* node) {
  g_node_from_last_default_action = node;
}

// static
std::unique_ptr<base::AutoReset<float>> TestAXNodeWrapper::SetScaleFactor(
    float value) {
  return std::make_unique<base::AutoReset<float>>(&g_scale_factor, value);
}

// static
void TestAXNodeWrapper::SetGlobalIsWebContent(bool is_web_content) {
  g_is_web_content = is_web_content;
}

// static
void TestAXNodeWrapper::SetHitTestResult(AXNode::AXID src_node_id,
                                         AXNode::AXID dst_node_id) {
  g_hit_test_result[src_node_id] = dst_node_id;
}

TestAXNodeWrapper::~TestAXNodeWrapper() {
  platform_node_->Destroy();
}

const AXNodeData& TestAXNodeWrapper::GetData() const {
  return node_->data();
}

const AXTreeData& TestAXNodeWrapper::GetTreeData() const {
  return tree_->data();
}

const AXTree::Selection TestAXNodeWrapper::GetUnignoredSelection() const {
  return tree_->GetUnignoredSelection();
}

AXNodePosition::AXPositionInstance TestAXNodeWrapper::CreateTextPositionAt(
    int offset) const {
  return ui::AXNodePosition::CreateTextPosition(
      GetTreeData().tree_id, node_->id(), offset,
      ax::mojom::TextAffinity::kDownstream);
}

gfx::NativeViewAccessible TestAXNodeWrapper::GetNativeViewAccessible() {
  return ax_platform_node()->GetNativeViewAccessible();
}

gfx::NativeViewAccessible TestAXNodeWrapper::GetParent() {
  TestAXNodeWrapper* parent_wrapper =
      GetOrCreate(tree_, node_->GetUnignoredParent());
  return parent_wrapper
             ? parent_wrapper->ax_platform_node()->GetNativeViewAccessible()
             : nullptr;
}

int TestAXNodeWrapper::GetChildCount() const {
  return InternalChildCount();
}

gfx::NativeViewAccessible TestAXNodeWrapper::ChildAtIndex(int index) {
  TestAXNodeWrapper* child_wrapper = InternalGetChild(index);
  return child_wrapper
             ? child_wrapper->ax_platform_node()->GetNativeViewAccessible()
             : nullptr;
}

gfx::Rect TestAXNodeWrapper::GetBoundsRect(
    const AXCoordinateSystem coordinate_system,
    const AXClippingBehavior clipping_behavior,
    AXOffscreenResult* offscreen_result) const {
  switch (coordinate_system) {
    case AXCoordinateSystem::kScreenPhysicalPixels:
      // For unit testing purposes, assume a device scale factor of 1 and fall
      // through.
    case AXCoordinateSystem::kScreenDIPs: {
      // We could optionally add clipping here if ever needed.
      gfx::RectF bounds = GetLocation();
      bounds.Offset(g_offset);

      // For test behavior only, for bounds that are offscreen we currently do
      // not apply clipping to the bounds but we still return the offscreen
      // status.
      if (offscreen_result) {
        *offscreen_result = DetermineOffscreenResult(bounds);
      }

      return gfx::ToEnclosingRect(bounds);
    }
    case AXCoordinateSystem::kRootFrame:
    case AXCoordinateSystem::kFrame:
      NOTIMPLEMENTED();
      return gfx::Rect();
  }
}

gfx::Rect TestAXNodeWrapper::GetInnerTextRangeBoundsRect(
    const int start_offset,
    const int end_offset,
    const AXCoordinateSystem coordinate_system,
    const AXClippingBehavior clipping_behavior,
    AXOffscreenResult* offscreen_result) const {
  switch (coordinate_system) {
    case AXCoordinateSystem::kScreenPhysicalPixels:
    // For unit testing purposes, assume a device scale factor of 1 and fall
    // through.
    case AXCoordinateSystem::kScreenDIPs: {
      gfx::RectF bounds = GetLocation();
      // This implementation currently only deals with text node that has role
      // kInlineTextBox and kStaticText.
      // For test purposes, assume node with kStaticText always has a single
      // child with role kInlineTextBox.
      if (GetData().role == ax::mojom::Role::kInlineTextBox) {
        bounds = GetInlineTextRect(start_offset, end_offset);
      } else if (GetData().role == ax::mojom::Role::kStaticText &&
                 InternalChildCount() > 0) {
        TestAXNodeWrapper* child = InternalGetChild(0);
        if (child != nullptr &&
            child->GetData().role == ax::mojom::Role::kInlineTextBox) {
          bounds = child->GetInlineTextRect(start_offset, end_offset);
        }
      }

      bounds.Offset(g_offset);

      // For test behavior only, for bounds that are offscreen we currently do
      // not apply clipping to the bounds but we still return the offscreen
      // status.
      if (offscreen_result) {
        *offscreen_result = DetermineOffscreenResult(bounds);
      }

      return gfx::ToEnclosingRect(bounds);
    }
    case AXCoordinateSystem::kRootFrame:
    case AXCoordinateSystem::kFrame:
      NOTIMPLEMENTED();
      return gfx::Rect();
  }
}

gfx::Rect TestAXNodeWrapper::GetHypertextRangeBoundsRect(
    const int start_offset,
    const int end_offset,
    const AXCoordinateSystem coordinate_system,
    const AXClippingBehavior clipping_behavior,
    AXOffscreenResult* offscreen_result) const {
  switch (coordinate_system) {
    case AXCoordinateSystem::kScreenPhysicalPixels:
    // For unit testing purposes, assume a device scale factor of 1 and fall
    // through.
    case AXCoordinateSystem::kScreenDIPs: {
      // Ignoring start, len, and clipped, as there's no clean way to map these
      // via unit tests.
      gfx::RectF bounds = GetLocation();
      bounds.Offset(g_offset);
      return gfx::ToEnclosingRect(bounds);
    }
    case AXCoordinateSystem::kRootFrame:
    case AXCoordinateSystem::kFrame:
      NOTIMPLEMENTED();
      return gfx::Rect();
  }
}

TestAXNodeWrapper* TestAXNodeWrapper::HitTestSyncInternal(int x, int y) {
  if (g_hit_test_result.find(node_->id()) != g_hit_test_result.end()) {
    int result_id = g_hit_test_result[node_->id()];
    AXNode* result_node = tree_->GetFromId(result_id);
    return GetOrCreate(tree_, result_node);
  }

  // Here we find the deepest child whose bounding box contains the given point.
  // The assumptions are that there are no overlapping bounding rects and that
  // all children have smaller bounding rects than their parents.
  if (!GetClippedScreenBoundsRect().Contains(gfx::Rect(x, y, 0, 0)))
    return nullptr;

  for (int i = 0; i < GetChildCount(); i++) {
    TestAXNodeWrapper* child = GetOrCreate(tree_, node_->children()[i]);
    if (!child)
      return nullptr;

    TestAXNodeWrapper* result = child->HitTestSyncInternal(x, y);
    if (result) {
      return result;
    }
  }
  return this;
}

gfx::NativeViewAccessible TestAXNodeWrapper::HitTestSync(
    int screen_physical_pixel_x,
    int screen_physical_pixel_y) const {
  const TestAXNodeWrapper* wrapper =
      const_cast<TestAXNodeWrapper*>(this)->HitTestSyncInternal(
          screen_physical_pixel_x / g_scale_factor,
          screen_physical_pixel_y / g_scale_factor);
  return wrapper ? wrapper->ax_platform_node()->GetNativeViewAccessible()
                 : nullptr;
}

gfx::NativeViewAccessible TestAXNodeWrapper::GetFocus() {
  auto focused = g_focused_node_in_tree.find(tree_);
  if (focused != g_focused_node_in_tree.end() &&
      focused->second->IsDescendantOf(node_)) {
    return GetOrCreate(tree_, focused->second)
        ->ax_platform_node()
        ->GetNativeViewAccessible();
  }
  return nullptr;
}

bool TestAXNodeWrapper::IsMinimized() const {
  return minimized_;
}

bool TestAXNodeWrapper::IsWebContent() const {
  return g_is_web_content;
}

// Walk the AXTree and ensure that all wrappers are created
void TestAXNodeWrapper::BuildAllWrappers(AXTree* tree, AXNode* node) {
  for (auto* child : node->children()) {
    TestAXNodeWrapper::GetOrCreate(tree, child);
    BuildAllWrappers(tree, child);
  }
}

void TestAXNodeWrapper::ResetNativeEventTarget() {
  native_event_target_ = gfx::kNullAcceleratedWidget;
}

AXPlatformNode* TestAXNodeWrapper::GetFromNodeID(int32_t id) {
  // Force creating all of the wrappers for this tree.
  BuildAllWrappers(tree_, node_);

  const auto iter = g_node_id_to_wrapper_map.find(id);
  if (iter != g_node_id_to_wrapper_map.end())
    return iter->second->ax_platform_node();

  return nullptr;
}

AXPlatformNode* TestAXNodeWrapper::GetFromTreeIDAndNodeID(
    const ui::AXTreeID& ax_tree_id,
    int32_t id) {
  // TestAXNodeWrapper only supports one accessibility tree.
  // Additional work would need to be done to support multiple trees.
  CHECK_EQ(GetTreeData().tree_id, ax_tree_id);
  return GetFromNodeID(id);
}

int TestAXNodeWrapper::GetIndexInParent() {
  return node_ ? int{node_->GetUnignoredIndexInParent()} : -1;
}

void TestAXNodeWrapper::ReplaceIntAttribute(int32_t node_id,
                                            ax::mojom::IntAttribute attribute,
                                            int32_t value) {
  if (!tree_)
    return;

  AXNode* node = tree_->GetFromId(node_id);
  if (!node)
    return;

  AXNodeData new_data = node->data();
  std::vector<std::pair<ax::mojom::IntAttribute, int32_t>>& attributes =
      new_data.int_attributes;

  base::EraseIf(attributes,
                [attribute](auto& pair) { return pair.first == attribute; });

  new_data.AddIntAttribute(attribute, value);
  node->SetData(new_data);
}

void TestAXNodeWrapper::ReplaceFloatAttribute(
    ax::mojom::FloatAttribute attribute,
    float value) {
  AXNodeData new_data = GetData();
  std::vector<std::pair<ax::mojom::FloatAttribute, float>>& attributes =
      new_data.float_attributes;

  base::EraseIf(attributes,
                [attribute](auto& pair) { return pair.first == attribute; });

  new_data.AddFloatAttribute(attribute, value);
  node_->SetData(new_data);
}

void TestAXNodeWrapper::ReplaceBoolAttribute(ax::mojom::BoolAttribute attribute,
                                             bool value) {
  AXNodeData new_data = GetData();
  std::vector<std::pair<ax::mojom::BoolAttribute, bool>>& attributes =
      new_data.bool_attributes;

  base::EraseIf(attributes,
                [attribute](auto& pair) { return pair.first == attribute; });

  new_data.AddBoolAttribute(attribute, value);
  node_->SetData(new_data);
}

void TestAXNodeWrapper::ReplaceStringAttribute(
    ax::mojom::StringAttribute attribute,
    std::string value) {
  AXNodeData new_data = GetData();
  std::vector<std::pair<ax::mojom::StringAttribute, std::string>>& attributes =
      new_data.string_attributes;

  base::EraseIf(attributes,
                [attribute](auto& pair) { return pair.first == attribute; });

  new_data.AddStringAttribute(attribute, value);
  node_->SetData(new_data);
}

void TestAXNodeWrapper::ReplaceTreeDataTextSelection(int32_t anchor_node_id,
                                                     int32_t anchor_offset,
                                                     int32_t focus_node_id,
                                                     int32_t focus_offset) {
  if (!tree_)
    return;

  AXTreeData new_tree_data = GetTreeData();
  new_tree_data.sel_anchor_object_id = anchor_node_id;
  new_tree_data.sel_anchor_offset = anchor_offset;
  new_tree_data.sel_focus_object_id = focus_node_id;
  new_tree_data.sel_focus_offset = focus_offset;

  tree_->UpdateData(new_tree_data);
}

bool TestAXNodeWrapper::IsTable() const {
  return node_->IsTable();
}

base::Optional<int> TestAXNodeWrapper::GetTableRowCount() const {
  return node_->GetTableRowCount();
}

base::Optional<int> TestAXNodeWrapper::GetTableColCount() const {
  return node_->GetTableColCount();
}

base::Optional<int> TestAXNodeWrapper::GetTableAriaRowCount() const {
  return node_->GetTableAriaRowCount();
}

base::Optional<int> TestAXNodeWrapper::GetTableAriaColCount() const {
  return node_->GetTableAriaColCount();
}

base::Optional<int> TestAXNodeWrapper::GetTableCellCount() const {
  return node_->GetTableCellCount();
}

base::Optional<bool> TestAXNodeWrapper::GetTableHasColumnOrRowHeaderNode()
    const {
  return node_->GetTableHasColumnOrRowHeaderNode();
}

std::vector<AXNode::AXID> TestAXNodeWrapper::GetColHeaderNodeIds() const {
  return node_->GetTableColHeaderNodeIds();
}

std::vector<AXNode::AXID> TestAXNodeWrapper::GetColHeaderNodeIds(
    int col_index) const {
  return node_->GetTableColHeaderNodeIds(col_index);
}

std::vector<AXNode::AXID> TestAXNodeWrapper::GetRowHeaderNodeIds() const {
  return node_->GetTableCellRowHeaderNodeIds();
}

std::vector<AXNode::AXID> TestAXNodeWrapper::GetRowHeaderNodeIds(
    int row_index) const {
  return node_->GetTableRowHeaderNodeIds(row_index);
}

bool TestAXNodeWrapper::IsTableRow() const {
  return node_->IsTableRow();
}

base::Optional<int> TestAXNodeWrapper::GetTableRowRowIndex() const {
  return node_->GetTableRowRowIndex();
}

bool TestAXNodeWrapper::IsTableCellOrHeader() const {
  return node_->IsTableCellOrHeader();
}

base::Optional<int> TestAXNodeWrapper::GetTableCellIndex() const {
  return node_->GetTableCellIndex();
}

base::Optional<int> TestAXNodeWrapper::GetTableCellColIndex() const {
  return node_->GetTableCellColIndex();
}

base::Optional<int> TestAXNodeWrapper::GetTableCellRowIndex() const {
  return node_->GetTableCellRowIndex();
}

base::Optional<int> TestAXNodeWrapper::GetTableCellColSpan() const {
  return node_->GetTableCellColSpan();
}

base::Optional<int> TestAXNodeWrapper::GetTableCellRowSpan() const {
  return node_->GetTableCellRowSpan();
}

base::Optional<int> TestAXNodeWrapper::GetTableCellAriaColIndex() const {
  return node_->GetTableCellAriaColIndex();
}

base::Optional<int> TestAXNodeWrapper::GetTableCellAriaRowIndex() const {
  return node_->GetTableCellAriaRowIndex();
}

base::Optional<int32_t> TestAXNodeWrapper::GetCellId(int row_index,
                                                     int col_index) const {
  AXNode* cell = node_->GetTableCellFromCoords(row_index, col_index);
  if (!cell)
    return base::nullopt;
  return cell->id();
}

gfx::AcceleratedWidget
TestAXNodeWrapper::GetTargetForNativeAccessibilityEvent() {
  return native_event_target_;
}

base::Optional<int32_t> TestAXNodeWrapper::CellIndexToId(int cell_index) const {
  AXNode* cell = node_->GetTableCellFromIndex(cell_index);
  if (!cell)
    return base::nullopt;
  return cell->id();
}

bool TestAXNodeWrapper::IsCellOrHeaderOfARIATable() const {
  return node_->IsCellOrHeaderOfARIATable();
}

bool TestAXNodeWrapper::IsCellOrHeaderOfARIAGrid() const {
  return node_->IsCellOrHeaderOfARIAGrid();
}

bool TestAXNodeWrapper::AccessibilityPerformAction(
    const ui::AXActionData& data) {
  switch (data.action) {
    case ax::mojom::Action::kScrollToPoint:
      g_offset = gfx::Vector2d(data.target_point.x(), data.target_point.y());
      return true;
    case ax::mojom::Action::kSetScrollOffset: {
      int scroll_x_min =
          GetData().GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin);
      int scroll_x_max =
          GetData().GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax);
      int scroll_y_min =
          GetData().GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin);
      int scroll_y_max =
          GetData().GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax);
      int scroll_x =
          base::ClampToRange(data.target_point.x(), scroll_x_min, scroll_x_max);
      int scroll_y =
          base::ClampToRange(data.target_point.y(), scroll_y_min, scroll_y_max);

      ReplaceIntAttribute(node_->id(), ax::mojom::IntAttribute::kScrollX,
                          scroll_x);
      ReplaceIntAttribute(node_->id(), ax::mojom::IntAttribute::kScrollY,
                          scroll_y);
      return true;
    }
    case ax::mojom::Action::kScrollToMakeVisible: {
      auto offset = node_->data().relative_bounds.bounds.OffsetFromOrigin();
      g_offset = gfx::Vector2d(-offset.x(), -offset.y());
      return true;
    }

    case ax::mojom::Action::kDoDefault: {
      // If a default action such as a click is performed on an element, it
      // could result in a selected state change. In which case, the element's
      // selected state no longer comes from focus action, so we should set
      // |kSelectedFromFocus| to false.
      if (GetData().HasBoolAttribute(
              ax::mojom::BoolAttribute::kSelectedFromFocus))
        ReplaceBoolAttribute(ax::mojom::BoolAttribute::kSelectedFromFocus,
                             false);

      switch (GetData().role) {
        case ax::mojom::Role::kListBoxOption:
        case ax::mojom::Role::kCell: {
          bool current_value =
              GetData().GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
          ReplaceBoolAttribute(ax::mojom::BoolAttribute::kSelected,
                               !current_value);
          break;
        }
        case ax::mojom::Role::kRadioButton:
        case ax::mojom::Role::kMenuItemRadio: {
          if (GetData().GetCheckedState() == ax::mojom::CheckedState::kTrue)
            ReplaceIntAttribute(
                node_->id(), ax::mojom::IntAttribute::kCheckedState,
                static_cast<int32_t>(ax::mojom::CheckedState::kFalse));
          else if (GetData().GetCheckedState() ==
                   ax::mojom::CheckedState::kFalse)
            ReplaceIntAttribute(
                node_->id(), ax::mojom::IntAttribute::kCheckedState,
                static_cast<int32_t>(ax::mojom::CheckedState::kTrue));
          break;
        }
        default:
          break;
      }
      SetNodeFromLastDefaultAction(node_);
      return true;
    }

    case ax::mojom::Action::kSetValue:
      if (GetData().IsRangeValueSupported()) {
        ReplaceFloatAttribute(ax::mojom::FloatAttribute::kValueForRange,
                              std::stof(data.value));
      } else if (GetData().role == ax::mojom::Role::kTextField) {
        ReplaceStringAttribute(ax::mojom::StringAttribute::kValue, data.value);
      }
      return true;

    case ax::mojom::Action::kSetSelection: {
      ReplaceIntAttribute(data.anchor_node_id,
                          ax::mojom::IntAttribute::kTextSelStart,
                          data.anchor_offset);
      ReplaceIntAttribute(data.focus_node_id,
                          ax::mojom::IntAttribute::kTextSelEnd,
                          data.focus_offset);
      ReplaceTreeDataTextSelection(data.anchor_node_id, data.anchor_offset,
                                   data.focus_node_id, data.focus_offset);
      return true;
    }

    case ax::mojom::Action::kFocus: {
      g_focused_node_in_tree[tree_] = node_;

      // The platform has select follows focus behavior:
      // https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_selection_follows_focus
      // For test purpose, we support select follows focus for all elements, and
      // not just single-selection container elements.
      if (SupportsSelected(GetData().role)) {
        ReplaceBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
        ReplaceBoolAttribute(ax::mojom::BoolAttribute::kSelectedFromFocus,
                             true);
      }

      return true;
    }

    case ax::mojom::Action::kShowContextMenu:
      g_node_from_last_show_context_menu = node_;
      return true;

    default:
      return true;
  }
}

base::string16 TestAXNodeWrapper::GetLocalizedRoleDescriptionForUnlabeledImage()
    const {
  return base::ASCIIToUTF16("Unlabeled image");
}

base::string16 TestAXNodeWrapper::GetLocalizedStringForLandmarkType() const {
  const AXNodeData& data = GetData();
  switch (data.role) {
    case ax::mojom::Role::kBanner:
    case ax::mojom::Role::kHeader:
      return base::ASCIIToUTF16("banner");

    case ax::mojom::Role::kComplementary:
      return base::ASCIIToUTF16("complementary");

    case ax::mojom::Role::kContentInfo:
    case ax::mojom::Role::kFooter:
      return base::ASCIIToUTF16("content information");

    case ax::mojom::Role::kRegion:
    case ax::mojom::Role::kSection:
      if (data.HasStringAttribute(ax::mojom::StringAttribute::kName))
        return base::ASCIIToUTF16("region");
      FALLTHROUGH;

    default:
      return {};
  }
}

base::string16 TestAXNodeWrapper::GetLocalizedStringForRoleDescription() const {
  const AXNodeData& data = GetData();

  switch (data.role) {
    case ax::mojom::Role::kArticle:
      return base::ASCIIToUTF16("article");

    case ax::mojom::Role::kAudio:
      return base::ASCIIToUTF16("audio");

    case ax::mojom::Role::kCode:
      return base::ASCIIToUTF16("code");

    case ax::mojom::Role::kColorWell:
      return base::ASCIIToUTF16("color picker");

    case ax::mojom::Role::kContentInfo:
      return base::ASCIIToUTF16("content information");

    case ax::mojom::Role::kDate:
      return base::ASCIIToUTF16("date picker");

    case ax::mojom::Role::kDateTime: {
      std::string input_type;
      if (data.GetStringAttribute(ax::mojom::StringAttribute::kInputType,
                                  &input_type)) {
        if (input_type == "datetime-local") {
          return base::ASCIIToUTF16("local date and time picker");
        } else if (input_type == "week") {
          return base::ASCIIToUTF16("week picker");
        }
      }
      return {};
    }

    case ax::mojom::Role::kDetails:
      return base::ASCIIToUTF16("details");

    case ax::mojom::Role::kEmphasis:
      return base::ASCIIToUTF16("emphasis");

    case ax::mojom::Role::kFigure:
      return base::ASCIIToUTF16("figure");

    case ax::mojom::Role::kFooter:
    case ax::mojom::Role::kFooterAsNonLandmark:
      return base::ASCIIToUTF16("footer");

    case ax::mojom::Role::kHeader:
    case ax::mojom::Role::kHeaderAsNonLandmark:
      return base::ASCIIToUTF16("header");

    case ax::mojom::Role::kMark:
      return base::ASCIIToUTF16("highlight");

    case ax::mojom::Role::kMeter:
      return base::ASCIIToUTF16("meter");

    case ax::mojom::Role::kSearchBox:
      return base::ASCIIToUTF16("search box");

    case ax::mojom::Role::kSection: {
      if (data.HasStringAttribute(ax::mojom::StringAttribute::kName))
        return base::ASCIIToUTF16("section");

      return {};
    }

    case ax::mojom::Role::kStatus:
      return base::ASCIIToUTF16("output");

    case ax::mojom::Role::kStrong:
      return base::ASCIIToUTF16("strong");

    case ax::mojom::Role::kTextField: {
      std::string input_type;
      if (data.GetStringAttribute(ax::mojom::StringAttribute::kInputType,
                                  &input_type)) {
        if (input_type == "email") {
          return base::ASCIIToUTF16("email");
        } else if (input_type == "tel") {
          return base::ASCIIToUTF16("telephone");
        } else if (input_type == "url") {
          return base::ASCIIToUTF16("url");
        }
      }
      return {};
    }

    case ax::mojom::Role::kTime:
      return base::ASCIIToUTF16("time");

    default:
      return {};
  }
}

base::string16 TestAXNodeWrapper::GetLocalizedStringForImageAnnotationStatus(
    ax::mojom::ImageAnnotationStatus status) const {
  switch (status) {
    case ax::mojom::ImageAnnotationStatus::kEligibleForAnnotation:
      return base::ASCIIToUTF16(
          "To get missing image descriptions, open the context menu.");
    case ax::mojom::ImageAnnotationStatus::kAnnotationPending:
      return base::ASCIIToUTF16("Getting description...");
    case ax::mojom::ImageAnnotationStatus::kAnnotationAdult:
      return base::ASCIIToUTF16(
          "Appears to contain adult content. No description available.");
    case ax::mojom::ImageAnnotationStatus::kAnnotationEmpty:
    case ax::mojom::ImageAnnotationStatus::kAnnotationProcessFailed:
      return base::ASCIIToUTF16("No description available.");
    case ax::mojom::ImageAnnotationStatus::kNone:
    case ax::mojom::ImageAnnotationStatus::kWillNotAnnotateDueToScheme:
    case ax::mojom::ImageAnnotationStatus::kIneligibleForAnnotation:
    case ax::mojom::ImageAnnotationStatus::kSilentlyEligibleForAnnotation:
    case ax::mojom::ImageAnnotationStatus::kAnnotationSucceeded:
      return base::string16();
  }

  NOTREACHED();
  return base::string16();
}

base::string16 TestAXNodeWrapper::GetStyleNameAttributeAsLocalizedString()
    const {
  AXNode* current_node = node_;
  while (current_node) {
    if (current_node->data().role == ax::mojom::Role::kMark)
      return base::ASCIIToUTF16("mark");
    current_node = current_node->parent();
  }
  return base::string16();
}

bool TestAXNodeWrapper::ShouldIgnoreHoveredStateForTesting() {
  return true;
}

bool TestAXNodeWrapper::HasVisibleCaretOrSelection() const {
  ui::AXTree::Selection unignored_selection = GetUnignoredSelection();
  int32_t focus_id = unignored_selection.focus_object_id;
  AXNode* focus_object = tree_->GetFromId(focus_id);
  if (!focus_object)
    return false;

  // Selection or caret will be visible in a focused editable area.
  if (GetData().HasState(ax::mojom::State::kEditable)) {
    return GetData().IsPlainTextField() ? focus_object == node_
                                        : focus_object->IsDescendantOf(node_);
  }

  // The selection will be visible in non-editable content only if it is not
  // collapsed into a caret.
  return (focus_id != unignored_selection.anchor_object_id ||
          unignored_selection.focus_offset !=
              unignored_selection.anchor_offset) &&
         focus_object->IsDescendantOf(node_);
}

std::set<AXPlatformNode*> TestAXNodeWrapper::GetReverseRelations(
    ax::mojom::IntAttribute attr) {
  DCHECK(IsNodeIdIntAttribute(attr));
  return GetNodesForNodeIds(tree_->GetReverseRelations(attr, GetData().id));
}

std::set<AXPlatformNode*> TestAXNodeWrapper::GetReverseRelations(
    ax::mojom::IntListAttribute attr) {
  DCHECK(IsNodeIdIntListAttribute(attr));
  return GetNodesForNodeIds(tree_->GetReverseRelations(attr, GetData().id));
}

const ui::AXUniqueId& TestAXNodeWrapper::GetUniqueId() const {
  return unique_id_;
}

TestAXNodeWrapper::TestAXNodeWrapper(AXTree* tree, AXNode* node)
    : tree_(tree), node_(node), platform_node_(AXPlatformNode::Create(this)) {
#if defined(OS_WIN)
  native_event_target_ = gfx::kMockAcceleratedWidget;
#else
  native_event_target_ = gfx::kNullAcceleratedWidget;
#endif
}

bool TestAXNodeWrapper::IsOrderedSetItem() const {
  return node_->IsOrderedSetItem();
}

bool TestAXNodeWrapper::IsOrderedSet() const {
  return node_->IsOrderedSet();
}

base::Optional<int> TestAXNodeWrapper::GetPosInSet() const {
  return node_->GetPosInSet();
}

base::Optional<int> TestAXNodeWrapper::GetSetSize() const {
  return node_->GetSetSize();
}

gfx::RectF TestAXNodeWrapper::GetLocation() const {
  return GetData().relative_bounds.bounds;
}

int TestAXNodeWrapper::InternalChildCount() const {
  return int{node_->GetUnignoredChildCount()};
}

TestAXNodeWrapper* TestAXNodeWrapper::InternalGetChild(int index) const {
  CHECK_GE(index, 0);
  CHECK_LT(index, InternalChildCount());
  return GetOrCreate(tree_, node_->GetUnignoredChildAtIndex(size_t{index}));
}

// Recursive helper function for GetUIADescendants. Aggregates all of the
// descendants for a given node within the descendants vector.
void TestAXNodeWrapper::UIADescendants(
    const AXNode* node,
    std::vector<gfx::NativeViewAccessible>* descendants) const {
  if (ShouldHideChildrenForUIA(node))
    return;

  for (auto it = node->UnignoredChildrenBegin();
       it != node->UnignoredChildrenEnd(); ++it) {
    descendants->emplace_back(ax_platform_node()
                                  ->GetDelegate()
                                  ->GetFromNodeID(it->id())
                                  ->GetNativeViewAccessible());
    UIADescendants(it.get(), descendants);
  }
}

const std::vector<gfx::NativeViewAccessible>
TestAXNodeWrapper::GetUIADescendants() const {
  std::vector<gfx::NativeViewAccessible> descendants;
  UIADescendants(node_, &descendants);
  return descendants;
}

// static
// Needs to stay in sync with AXPlatformNodeWin::ShouldHideChildrenForUIA.
bool TestAXNodeWrapper::ShouldHideChildrenForUIA(const AXNode* node) {
  if (!node)
    return false;

  auto role = node->data().role;

  if (ui::HasPresentationalChildren(role))
    return true;

  switch (role) {
    case ax::mojom::Role::kLink:
    case ax::mojom::Role::kTextField:
      return true;
    default:
      return false;
  }
}

gfx::RectF TestAXNodeWrapper::GetInlineTextRect(const int start_offset,
                                                const int end_offset) const {
  DCHECK(start_offset >= 0 && end_offset >= 0 && start_offset <= end_offset);
  const std::vector<int32_t>& character_offsets = GetData().GetIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets);
  gfx::RectF location = GetLocation();
  gfx::RectF bounds;

  switch (static_cast<ax::mojom::WritingDirection>(
      GetData().GetIntAttribute(ax::mojom::IntAttribute::kTextDirection))) {
    // Currently only kNone and kLtr are supported text direction.
    case ax::mojom::WritingDirection::kNone:
    case ax::mojom::WritingDirection::kLtr: {
      int start_pixel_offset =
          start_offset > 0 ? character_offsets[start_offset - 1] : location.x();
      int end_pixel_offset =
          end_offset > 0 ? character_offsets[end_offset - 1] : location.x();
      bounds =
          gfx::RectF(start_pixel_offset, location.y(),
                     end_pixel_offset - start_pixel_offset, location.height());
      break;
    }
    default:
      NOTIMPLEMENTED();
  }
  return bounds;
}

AXOffscreenResult TestAXNodeWrapper::DetermineOffscreenResult(
    gfx::RectF bounds) const {
  if (!tree_ || !tree_->root())
    return AXOffscreenResult::kOnscreen;

  const AXNodeData& root_web_area_node_data = tree_->root()->data();
  gfx::RectF root_web_area_bounds =
      root_web_area_node_data.relative_bounds.bounds;

  // For testing, we only look at the current node's bound relative to the root
  // web area bounds to determine offscreen status. We currently do not look at
  // the bounds of the immediate parent of the node for determining offscreen
  // status.
  // We only determine offscreen result if the root web area bounds is actually
  // set in the test. We default the offscreen result of every other situation
  // to AXOffscreenResult::kOnscreen.
  if (!root_web_area_bounds.IsEmpty()) {
    bounds.Intersect(root_web_area_bounds);
    if (bounds.IsEmpty())
      return AXOffscreenResult::kOffscreen;
  }
  return AXOffscreenResult::kOnscreen;
}

}  // namespace ui
