// Copyright 2018 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/ax_assistant_structure.h"

#include <string>

#include "base/logging.h"
#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_serializable_tree.h"
#include "ui/accessibility/platform/ax_android_constants.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/range/range.h"
#include "ui/gfx/transform.h"

namespace ui {

namespace {

bool HasFocusableChild(const AXNode* node) {
  for (auto* child : node->children()) {
    if (child->data().HasState(ax::mojom::State::kFocusable) ||
        HasFocusableChild(child)) {
      return true;
    }
  }
  return false;
}

bool HasOnlyTextChildren(const AXNode* node) {
  for (auto* child : node->children()) {
    if (!child->IsTextNode())
      return false;
  }
  return true;
}

// TODO(muyuanli): share with BrowserAccessibility.
bool IsSimpleTextControl(const AXNode* node, uint32_t state) {
  return (node->data().role == ax::mojom::Role::kTextField ||
          node->data().role == ax::mojom::Role::kTextFieldWithComboBox ||
          node->data().role == ax::mojom::Role::kSearchBox ||
          node->data().HasBoolAttribute(
              ax::mojom::BoolAttribute::kEditableRoot)) &&
         !node->data().HasState(ax::mojom::State::kRichlyEditable);
}

bool IsRichTextEditable(const AXNode* node) {
  const AXNode* parent = node->parent();
  return node->data().HasState(ax::mojom::State::kRichlyEditable) &&
         (!parent ||
          !parent->data().HasState(ax::mojom::State::kRichlyEditable));
}

bool IsNativeTextControl(const AXNode* node) {
  const std::string& html_tag =
      node->data().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
  if (html_tag == "input") {
    std::string input_type;
    if (!node->data().GetHtmlAttribute("type", &input_type))
      return true;
    return input_type.empty() || input_type == "email" ||
           input_type == "password" || input_type == "search" ||
           input_type == "tel" || input_type == "text" || input_type == "url" ||
           input_type == "number";
  }
  return html_tag == "textarea";
}

bool IsLeaf(const AXNode* node) {
  if (node->child_count() == 0)
    return true;

  if (IsNativeTextControl(node) || node->IsTextNode()) {
    return true;
  }

  switch (node->data().role) {
    case ax::mojom::Role::kImage:
    case ax::mojom::Role::kMeter:
    case ax::mojom::Role::kScrollBar:
    case ax::mojom::Role::kSlider:
    case ax::mojom::Role::kSplitter:
    case ax::mojom::Role::kProgressIndicator:
    case ax::mojom::Role::kDate:
    case ax::mojom::Role::kDateTime:
    case ax::mojom::Role::kInputTime:
      return true;
    default:
      return false;
  }
}

base::string16 GetInnerText(const AXNode* node) {
  if (node->IsTextNode()) {
    return node->data().GetString16Attribute(ax::mojom::StringAttribute::kName);
  }
  base::string16 text;
  for (auto* child : node->children()) {
    text += GetInnerText(child);
  }
  return text;
}

base::string16 GetValue(const AXNode* node, bool show_password) {
  base::string16 value =
      node->data().GetString16Attribute(ax::mojom::StringAttribute::kValue);

  if (value.empty() &&
      (IsSimpleTextControl(node, node->data().state) ||
       IsRichTextEditable(node)) &&
      !IsNativeTextControl(node)) {
    value = GetInnerText(node);
  }

  if (node->data().HasState(ax::mojom::State::kProtected)) {
    if (!show_password) {
      value = base::string16(value.size(), kSecurePasswordBullet);
    }
  }

  return value;
}

bool HasOnlyTextAndImageChildren(const AXNode* node) {
  for (auto* child : node->children()) {
    if (child->data().role != ax::mojom::Role::kStaticText &&
        child->data().role != ax::mojom::Role::kImage) {
      return false;
    }
  }
  return true;
}

bool IsFocusable(const AXNode* node) {
  if (node->data().role == ax::mojom::Role::kIframe ||
      node->data().role == ax::mojom::Role::kIframePresentational ||
      (node->data().role == ax::mojom::Role::kRootWebArea && node->parent())) {
    return node->data().HasStringAttribute(ax::mojom::StringAttribute::kName);
  }
  return node->data().HasState(ax::mojom::State::kFocusable);
}

base::string16 GetText(const AXNode* node, bool show_password) {
  if (node->data().role == ax::mojom::Role::kWebArea ||
      node->data().role == ax::mojom::Role::kIframe ||
      node->data().role == ax::mojom::Role::kIframePresentational) {
    return base::string16();
  }

  ax::mojom::NameFrom name_from = static_cast<ax::mojom::NameFrom>(
      node->data().GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
  if (ui::IsListItem(node->data().role) &&
      name_from == ax::mojom::NameFrom::kContents) {
    if (node->child_count() > 0 && !HasOnlyTextChildren(node))
      return base::string16();
  }

  base::string16 value = GetValue(node, show_password);

  if (!value.empty()) {
    if (node->data().HasState(ax::mojom::State::kEditable))
      return value;

    switch (node->data().role) {
      case ax::mojom::Role::kComboBoxMenuButton:
      case ax::mojom::Role::kTextFieldWithComboBox:
      case ax::mojom::Role::kPopUpButton:
      case ax::mojom::Role::kTextField:
        return value;
      default:
        break;
    }
  }

  if (node->data().role == ax::mojom::Role::kColorWell) {
    unsigned int color = static_cast<unsigned int>(
        node->data().GetIntAttribute(ax::mojom::IntAttribute::kColorValue));
    unsigned int red = color >> 16 & 0xFF;
    unsigned int green = color >> 8 & 0xFF;
    unsigned int blue = color >> 0 & 0xFF;
    return base::UTF8ToUTF16(
        base::StringPrintf("#%02X%02X%02X", red, green, blue));
  }

  base::string16 text =
      node->data().GetString16Attribute(ax::mojom::StringAttribute::kName);
  base::string16 description = node->data().GetString16Attribute(
      ax::mojom::StringAttribute::kDescription);
  if (!description.empty()) {
    if (!text.empty())
      text += base::ASCIIToUTF16(" ");
    text += description;
  }

  if (text.empty())
    text = value;

  if (node->data().role == ax::mojom::Role::kRootWebArea)
    return text;

  if (text.empty() &&
      (HasOnlyTextChildren(node) ||
       (IsFocusable(node) && HasOnlyTextAndImageChildren(node)))) {
    for (auto* child : node->children()) {
      text += GetText(child, show_password);
    }
  }

  if (text.empty() && (ui::IsLink(node->data().role) ||
                       node->data().role == ax::mojom::Role::kImage)) {
    base::string16 url =
        node->data().GetString16Attribute(ax::mojom::StringAttribute::kUrl);
    text = AXUrlBaseText(url);
  }
  return text;
}

// Get string representation of ax::mojom::Role. We are not using ToString() in
// ax_enums.h since the names are subject to change in the future and
// we are only interested in a subset of the roles.
base::Optional<std::string> AXRoleToString(ax::mojom::Role role) {
  switch (role) {
    case ax::mojom::Role::kArticle:
      return base::Optional<std::string>("article");
    case ax::mojom::Role::kBanner:
      return base::Optional<std::string>("banner");
    case ax::mojom::Role::kCaption:
      return base::Optional<std::string>("caption");
    case ax::mojom::Role::kComplementary:
      return base::Optional<std::string>("complementary");
    case ax::mojom::Role::kDate:
      return base::Optional<std::string>("date");
    case ax::mojom::Role::kDateTime:
      return base::Optional<std::string>("date_time");
    case ax::mojom::Role::kDefinition:
      return base::Optional<std::string>("definition");
    case ax::mojom::Role::kDetails:
      return base::Optional<std::string>("details");
    case ax::mojom::Role::kDocument:
      return base::Optional<std::string>("document");
    case ax::mojom::Role::kFeed:
      return base::Optional<std::string>("feed");
    case ax::mojom::Role::kHeading:
      return base::Optional<std::string>("heading");
    case ax::mojom::Role::kIframe:
      return base::Optional<std::string>("iframe");
    case ax::mojom::Role::kIframePresentational:
      return base::Optional<std::string>("iframe_presentational");
    case ax::mojom::Role::kList:
      return base::Optional<std::string>("list");
    case ax::mojom::Role::kListItem:
      return base::Optional<std::string>("list_item");
    case ax::mojom::Role::kMain:
      return base::Optional<std::string>("main");
    case ax::mojom::Role::kParagraph:
      return base::Optional<std::string>("paragraph");
    default:
      return base::Optional<std::string>();
  }
}

AssistantNode* AddChild(AssistantTree* tree) {
  auto node = std::make_unique<AssistantNode>();
  tree->nodes.push_back(std::move(node));
  return tree->nodes.back().get();
}

struct WalkAXTreeConfig {
  bool should_select_leaf;
  const bool show_password;
};

void WalkAXTreeDepthFirst(const AXNode* node,
                          const gfx::Rect& rect,
                          const AXTreeUpdate& update,
                          const AXTree* tree,
                          WalkAXTreeConfig* config,
                          AssistantTree* assistant_tree,
                          AssistantNode* result) {
  result->text = GetText(node, config->show_password);
  result->class_name =
      AXRoleToAndroidClassName(node->data().role, node->parent() != nullptr);
  result->role = AXRoleToString(node->data().role);

  result->text_size = -1.0;
  result->bgcolor = 0;
  result->color = 0;
  result->bold = 0;
  result->italic = 0;
  result->line_through = 0;
  result->underline = 0;

  if (node->data().HasFloatAttribute(ax::mojom::FloatAttribute::kFontSize)) {
    gfx::RectF text_size_rect(
        0, 0, 1,
        node->data().GetFloatAttribute(ax::mojom::FloatAttribute::kFontSize));
    gfx::Rect scaled_text_size_rect =
        gfx::ToEnclosingRect(tree->RelativeToTreeBounds(node, text_size_rect));
    result->text_size = scaled_text_size_rect.height();

    result->color =
        node->data().GetIntAttribute(ax::mojom::IntAttribute::kColor);
    result->bgcolor =
        node->data().GetIntAttribute(ax::mojom::IntAttribute::kBackgroundColor);
    result->bold = node->data().HasTextStyle(ax::mojom::TextStyle::kBold);
    result->italic = node->data().HasTextStyle(ax::mojom::TextStyle::kItalic);
    result->line_through =
        node->data().HasTextStyle(ax::mojom::TextStyle::kLineThrough);
    result->underline =
        node->data().HasTextStyle(ax::mojom::TextStyle::kUnderline);
  }

  const gfx::Rect& absolute_rect =
      gfx::ToEnclosingRect(tree->GetTreeBounds(node));
  gfx::Rect parent_relative_rect = absolute_rect;
  bool is_root = node->parent() == nullptr;
  if (!is_root) {
    parent_relative_rect.Offset(-rect.OffsetFromOrigin());
  }
  result->rect = gfx::Rect(parent_relative_rect.x(), parent_relative_rect.y(),
                           absolute_rect.width(), absolute_rect.height());

  if (IsLeaf(node) && update.has_tree_data) {
    int start_selection = 0;
    int end_selection = 0;
    if (update.tree_data.sel_anchor_object_id == node->id()) {
      start_selection = update.tree_data.sel_anchor_offset;
      config->should_select_leaf = true;
    }

    if (config->should_select_leaf) {
      end_selection =
          static_cast<int32_t>(GetText(node, config->show_password).length());
    }

    if (update.tree_data.sel_focus_object_id == node->id()) {
      end_selection = update.tree_data.sel_focus_offset;
      config->should_select_leaf = false;
    }
    if (end_selection > 0)
      result->selection =
          base::make_optional<gfx::Range>(start_selection, end_selection);
  }

  for (auto* child : node->children()) {
    auto* n = AddChild(assistant_tree);
    result->children_indices.push_back(assistant_tree->nodes.size() - 1);
    WalkAXTreeDepthFirst(child, absolute_rect, update, tree, config,
                         assistant_tree, n);
  }
}

}  // namespace

AssistantNode::AssistantNode() = default;
AssistantNode::AssistantNode(const AssistantNode& other) = default;
AssistantNode::~AssistantNode() = default;

AssistantTree::AssistantTree() = default;
AssistantTree::~AssistantTree() = default;

std::unique_ptr<AssistantTree> CreateAssistantTree(const AXTreeUpdate& update,
                                                   bool show_password) {
  auto tree = std::make_unique<AXSerializableTree>();
  auto assistant_tree = std::make_unique<AssistantTree>();
  auto* root = AddChild(assistant_tree.get());
  if (!tree->Unserialize(update))
    LOG(FATAL) << tree->error();
  WalkAXTreeConfig config{
      false,         // should_select_leaf
      show_password  // show_password
  };
  WalkAXTreeDepthFirst(tree->root(), gfx::Rect(), update, tree.get(), &config,
                       assistant_tree.get(), root);
  return assistant_tree;
}

base::string16 AXUrlBaseText(base::string16 url) {
  // Given a url like http://foo.com/bar/baz.png, just return the
  // base text, e.g., "baz".
  int trailing_slashes = 0;
  while (url.size() - trailing_slashes > 0 &&
         url[url.size() - trailing_slashes - 1] == '/') {
    trailing_slashes++;
  }
  if (trailing_slashes)
    url = url.substr(0, url.size() - trailing_slashes);
  size_t slash_index = url.rfind('/');
  if (slash_index != std::string::npos)
    url = url.substr(slash_index + 1);
  size_t dot_index = url.rfind('.');
  if (dot_index != std::string::npos)
    url = url.substr(0, dot_index);
  return url;
}

const char* AXRoleToAndroidClassName(ax::mojom::Role role, bool has_parent) {
  switch (role) {
    case ax::mojom::Role::kSearchBox:
    case ax::mojom::Role::kSpinButton:
    case ax::mojom::Role::kTextField:
    case ax::mojom::Role::kTextFieldWithComboBox:
      return kAXEditTextClassname;
    case ax::mojom::Role::kSlider:
      return kAXSeekBarClassname;
    case ax::mojom::Role::kColorWell:
    case ax::mojom::Role::kComboBoxMenuButton:
    case ax::mojom::Role::kDate:
    case ax::mojom::Role::kPopUpButton:
    case ax::mojom::Role::kInputTime:
      return kAXSpinnerClassname;
    case ax::mojom::Role::kButton:
    case ax::mojom::Role::kMenuButton:
      return kAXButtonClassname;
    case ax::mojom::Role::kCheckBox:
    case ax::mojom::Role::kSwitch:
      return kAXCheckBoxClassname;
    case ax::mojom::Role::kRadioButton:
      return kAXRadioButtonClassname;
    case ax::mojom::Role::kToggleButton:
      return kAXToggleButtonClassname;
    case ax::mojom::Role::kCanvas:
    case ax::mojom::Role::kImage:
    case ax::mojom::Role::kSvgRoot:
      return kAXImageClassname;
    case ax::mojom::Role::kMeter:
    case ax::mojom::Role::kProgressIndicator:
      return kAXProgressBarClassname;
    case ax::mojom::Role::kTabList:
      return kAXTabWidgetClassname;
    case ax::mojom::Role::kGrid:
    case ax::mojom::Role::kTreeGrid:
    case ax::mojom::Role::kTable:
      return kAXGridViewClassname;
    case ax::mojom::Role::kList:
    case ax::mojom::Role::kListBox:
    case ax::mojom::Role::kDescriptionList:
      return kAXListViewClassname;
    case ax::mojom::Role::kDialog:
      return kAXDialogClassname;
    case ax::mojom::Role::kRootWebArea:
      return has_parent ? kAXViewClassname : kAXWebViewClassname;
    case ax::mojom::Role::kMenuItem:
    case ax::mojom::Role::kMenuItemCheckBox:
    case ax::mojom::Role::kMenuItemRadio:
      return kAXMenuItemClassname;
    default:
      return kAXViewClassname;
  }
}

}  // namespace ui
