// Copyright 2019 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 "content/browser/accessibility/accessibility_tree_formatter_base.h"

#include <stddef.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/check_op.h"
#include "base/strings/pattern.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents.h"

namespace content {

namespace {

const char kIndentSymbol = '+';
const int kIndentSymbolCount = 2;
const char kSkipString[] = "@NO_DUMP";
const char kSkipChildren[] = "@NO_CHILDREN_DUMP";

}  // namespace

//
// PropertyNode
//

// static
PropertyNode PropertyNode::FromPropertyFilter(
    const ui::AXPropertyFilter& filter) {
  // Property invocation: property_str expected format is
  // prop_name or prop_name(arg1, ... argN).
  PropertyNode root;
  const std::string& property_str = filter.property_str;
  Parse(&root, property_str.begin(), property_str.end());

  PropertyNode* node = &root.parameters[0];

  // Expel a trailing wildcard if any.
  node->original_property =
      property_str.substr(0, property_str.find_last_of('*'));

  // Line indexes filter: filter_str expected format is
  // :line_num_1, ... :line_num_N, a comma separated list of line indexes
  // the property should be queried for. For example, ":1,:5,:7" indicates that
  // the property should called for objects placed on 1, 5 and 7 lines only.
  const std::string& filter_str = filter.filter_str;
  if (!filter_str.empty()) {
    node->line_indexes =
        base::SplitString(filter_str, std::string(1, ','),
                          base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  }

  return std::move(*node);
}

PropertyNode::PropertyNode() = default;
PropertyNode::PropertyNode(PropertyNode&& o)
    : key(std::move(o.key)),
      target(std::move(o.target)),
      name_or_value(std::move(o.name_or_value)),
      parameters(std::move(o.parameters)),
      original_property(std::move(o.original_property)),
      line_indexes(std::move(o.line_indexes)) {}
PropertyNode::~PropertyNode() = default;

PropertyNode& PropertyNode::operator=(PropertyNode&& o) {
  key = std::move(o.key);
  target = std::move(o.target);
  name_or_value = std::move(o.name_or_value);
  parameters = std::move(o.parameters);
  original_property = std::move(o.original_property);
  line_indexes = std::move(o.line_indexes);
  return *this;
}

PropertyNode::operator bool() const {
  return !name_or_value.empty();
}

bool PropertyNode::IsMatching(const std::string& pattern) const {
  // Looking for exact property match. Expel a trailing whildcard from
  // the property filter to handle filters like AXRole*.
  return name_or_value.compare(0, name_or_value.find_last_of('*'), pattern) ==
         0;
}

bool PropertyNode::IsArray() const {
  return name_or_value == "[]";
}

bool PropertyNode::IsDict() const {
  return name_or_value == "{}";
}

base::Optional<int> PropertyNode::AsInt() const {
  int value = 0;
  if (!base::StringToInt(name_or_value, &value)) {
    return base::nullopt;
  }
  return value;
}

const PropertyNode* PropertyNode::FindKey(const char* refkey) const {
  for (const auto& param : parameters) {
    if (param.key == refkey) {
      return &param;
    }
  }
  return nullptr;
}

base::Optional<std::string> PropertyNode::FindStringKey(
    const char* refkey) const {
  for (const auto& param : parameters) {
    if (param.key == refkey) {
      return param.name_or_value;
    }
  }
  return base::nullopt;
}

base::Optional<int> PropertyNode::FindIntKey(const char* refkey) const {
  for (const auto& param : parameters) {
    if (param.key == refkey) {
      return param.AsInt();
    }
  }
  return base::nullopt;
}

std::string PropertyNode::ToString() const {
  std::string out;
  for (const auto& index : line_indexes) {
    if (!out.empty()) {
      out += ',';
    }
    out += index;
  }
  if (!out.empty()) {
    out += ';';
  }

  if (!key.empty()) {
    out += key + ": ";
  }

  if (!target.empty()) {
    out += target + '.';
  }
  out += name_or_value;
  if (parameters.size()) {
    out += '(';
    for (size_t i = 0; i < parameters.size(); i++) {
      if (i != 0) {
        out += ", ";
      }
      out += parameters[i].ToString();
    }
    out += ')';
  }
  return out;
}

// private
PropertyNode::PropertyNode(PropertyNode::iterator key_begin,
                           PropertyNode::iterator key_end,
                           const std::string& name_or_value)
    : key(key_begin, key_end) {
  Set(name_or_value.begin(), name_or_value.end());
}
PropertyNode::PropertyNode(PropertyNode::iterator begin,
                           PropertyNode::iterator end) {
  Set(begin, end);
}
PropertyNode::PropertyNode(PropertyNode::iterator key_begin,
                           PropertyNode::iterator key_end,
                           PropertyNode::iterator value_begin,
                           PropertyNode::iterator value_end)
    : key(key_begin, key_end), name_or_value(value_begin, value_end) {
  Set(value_begin, value_end);
}

void PropertyNode::Set(PropertyNode::iterator begin,
                       PropertyNode::iterator end) {
  PropertyNode::iterator dot_operator = std::find(begin, end, '.');
  if (dot_operator != end) {
    target = std::string(begin, dot_operator);
    name_or_value = std::string(dot_operator + 1, end);
  } else {
    name_or_value = std::string(begin, end);
  }
}

// private static
PropertyNode::iterator PropertyNode::Parse(PropertyNode* node,
                                           PropertyNode::iterator begin,
                                           PropertyNode::iterator end) {
  auto iter = begin;
  auto key_begin = end, key_end = end;
  while (iter != end) {
    // Subnode begins: create a new node, record its name and parse its
    // arguments.
    if (*iter == '(') {
      node->parameters.push_back(PropertyNode(key_begin, key_end, begin, iter));
      key_begin = key_end = end;
      begin = iter = Parse(&node->parameters.back(), ++iter, end);
      continue;
    }

    // Subnode begins: a special case for arrays, which have [arg1, ..., argN]
    // form.
    if (*iter == '[') {
      node->parameters.push_back(PropertyNode(key_begin, key_end, "[]"));
      key_begin = key_end = end;
      begin = iter = Parse(&node->parameters.back(), ++iter, end);
      continue;
    }

    // Subnode begins: a special case for dictionaries of {key1: value1, ...,
    // key2: value2} form.
    if (*iter == '{') {
      node->parameters.push_back(PropertyNode(key_begin, key_end, "{}"));
      key_begin = key_end = end;
      begin = iter = Parse(&node->parameters.back(), ++iter, end);
      continue;
    }

    // Subnode ends.
    if (*iter == ')' || *iter == ']' || *iter == '}') {
      if (begin != iter) {
        node->parameters.push_back(
            PropertyNode(key_begin, key_end, begin, iter));
        key_begin = key_end = end;
      }
      return ++iter;
    }

    // Dictionary key
    auto maybe_key_end = end;
    if (*iter == ':') {
      maybe_key_end = iter++;
    }

    // Skip spaces, adjust new node start.
    if (*iter == ' ') {
      if (maybe_key_end != end) {
        key_begin = begin;
        key_end = maybe_key_end;
      }
      begin = ++iter;
      continue;
    }

    // Subsequent scalar param case.
    if (*iter == ',' && begin != iter) {
      node->parameters.push_back(PropertyNode(key_begin, key_end, begin, iter));
      iter++;
      key_begin = key_end = end;
      begin = iter;
      continue;
    }

    iter++;
  }

  // Single scalar param case.
  if (begin != iter) {
    node->parameters.push_back(PropertyNode(begin, iter));
  }
  return iter;
}

//
// AccessibilityTreeFormatter
//

// static
std::string AccessibilityTreeFormatterBase::DumpAccessibilityTreeFromManager(
    BrowserAccessibilityManager* ax_mgr,
    bool internal,
    std::vector<AXPropertyFilter> property_filters) {
  std::unique_ptr<AccessibilityTreeFormatter> formatter;
  if (internal)
    formatter = std::make_unique<AccessibilityTreeFormatterBlink>();
  else
    formatter = Create();
  std::string accessibility_contents;
  formatter->SetPropertyFilters(property_filters);
  std::unique_ptr<base::DictionaryValue> dict =
      static_cast<AccessibilityTreeFormatterBase*>(formatter.get())
          ->BuildAccessibilityTree(ax_mgr->GetRoot());
  formatter->FormatAccessibilityTree(*dict, &accessibility_contents);
  return accessibility_contents;
}

bool AccessibilityTreeFormatter::MatchesPropertyFilters(
    const std::vector<AXPropertyFilter>& property_filters,
    const std::string& text,
    bool default_result) {
  bool allow = default_result;
  for (const auto& filter : property_filters) {
    // Either
    //   1) the line matches a filter pattern, for example, AXSubrole=* filter
    //      will match AXSubrole=AXTerm line or
    //   2) a property on the line is exactly equal to the filter pattern, for
    //      example, AXSubrole filter will match AXSubrole=AXTerm line.
    if (base::MatchPattern(text, filter.match_str) ||
        (filter.match_str.length() > 0 &&
         filter.match_str.find('=') == std::string::npos &&
         filter.match_str[filter.match_str.length() - 1] != '*' &&
         base::MatchPattern(text, filter.match_str + "=*"))) {
      switch (filter.type) {
        case AXPropertyFilter::ALLOW_EMPTY:
          allow = true;
          break;
        case AXPropertyFilter::ALLOW:
          allow = (!base::MatchPattern(text, "*=''"));
          break;
        case AXPropertyFilter::DENY:
          allow = false;
          break;
      }
    }
  }
  return allow;
}

bool AccessibilityTreeFormatter::MatchesNodeFilters(
    const std::vector<AXNodeFilter>& node_filters,
    const base::DictionaryValue& dict) {
  for (const auto& filter : node_filters) {
    std::string value;
    if (!dict.GetString(filter.property, &value)) {
      continue;
    }
    if (base::MatchPattern(value, filter.pattern)) {
      return true;
    }
  }
  return false;
}

AccessibilityTreeFormatterBase::AccessibilityTreeFormatterBase() = default;

AccessibilityTreeFormatterBase::~AccessibilityTreeFormatterBase() = default;

void AccessibilityTreeFormatterBase::FormatAccessibilityTree(
    const base::DictionaryValue& dict,
    std::string* contents) {
  RecursiveFormatAccessibilityTree(dict, contents);
}

void AccessibilityTreeFormatterBase::FormatAccessibilityTreeForTesting(
    ui::AXPlatformNodeDelegate* root,
    std::string* contents) {
  auto* node_internal = BrowserAccessibility::FromAXPlatformNodeDelegate(root);
  DCHECK(node_internal);
  FormatAccessibilityTree(*BuildAccessibilityTree(node_internal), contents);
}

std::unique_ptr<base::DictionaryValue>
AccessibilityTreeFormatterBase::FilterAccessibilityTree(
    const base::DictionaryValue& dict) {
  auto filtered_dict = std::make_unique<base::DictionaryValue>();
  ProcessTreeForOutput(dict, filtered_dict.get());
  const base::ListValue* children;
  if (dict.GetList(kChildrenDictAttr, &children) && !children->empty()) {
    const base::DictionaryValue* child_dict;
    auto filtered_children = std::make_unique<base::ListValue>();
    for (size_t i = 0; i < children->GetSize(); i++) {
      children->GetDictionary(i, &child_dict);
      auto filtered_child = FilterAccessibilityTree(*child_dict);
      filtered_children->Append(std::move(filtered_child));
    }
    filtered_dict->Set(kChildrenDictAttr, std::move(filtered_children));
  }
  return filtered_dict;
}

void AccessibilityTreeFormatterBase::RecursiveFormatAccessibilityTree(
    const base::DictionaryValue& dict,
    std::string* contents,
    int depth) {
  // Check dictionary against node filters, may require us to skip this node
  // and its children.
  if (MatchesNodeFilters(dict))
    return;

  std::string indent = std::string(depth * kIndentSymbolCount, kIndentSymbol);
  std::string line = indent + ProcessTreeForOutput(dict);
  if (line.find(kSkipString) != std::string::npos)
    return;

  // Normalize any Windows-style line endings by removing \r.
  base::RemoveChars(line, "\r", &line);

  // Replace literal newlines with "<newline>"
  base::ReplaceChars(line, "\n", "<newline>", &line);

  *contents += line + "\n";
  if (line.find(kSkipChildren) != std::string::npos)
    return;

  const base::ListValue* children;
  if (!dict.GetList(kChildrenDictAttr, &children))
    return;
  const base::DictionaryValue* child_dict;
  for (size_t i = 0; i < children->GetSize(); i++) {
    children->GetDictionary(i, &child_dict);
    RecursiveFormatAccessibilityTree(*child_dict, contents, depth + 1);
  }
}

void AccessibilityTreeFormatterBase::SetPropertyFilters(
    const std::vector<AXPropertyFilter>& property_filters) {
  property_filters_ = property_filters;
}

void AccessibilityTreeFormatterBase::SetNodeFilters(
    const std::vector<AXNodeFilter>& node_filters) {
  node_filters_ = node_filters;
}

void AccessibilityTreeFormatterBase::set_show_ids(bool show_ids) {
  show_ids_ = show_ids;
}

base::FilePath::StringType
AccessibilityTreeFormatterBase::GetVersionSpecificExpectedFileSuffix() {
  return FILE_PATH_LITERAL("");
}

std::vector<PropertyNode>
AccessibilityTreeFormatterBase::PropertyFilterNodesFor(
    const std::string& line_index) const {
  std::vector<PropertyNode> list;
  for (const auto& filter : property_filters_) {
    PropertyNode property_node = PropertyNode::FromPropertyFilter(filter);

    // Filter out if doesn't match line index (if specified).
    if (!property_node.line_indexes.empty() &&
        std::find(property_node.line_indexes.begin(),
                  property_node.line_indexes.end(),
                  line_index) == property_node.line_indexes.end()) {
      continue;
    }

    switch (filter.type) {
      case AXPropertyFilter::ALLOW_EMPTY:
      case AXPropertyFilter::ALLOW:
        list.push_back(std::move(property_node));
        break;
      case AXPropertyFilter::DENY:
        break;
      default:
        break;
    }
  }
  return list;
}

bool AccessibilityTreeFormatterBase::HasMatchAllPropertyFilter() const {
  for (const auto& filter : property_filters_) {
    if (filter.type == AXPropertyFilter::ALLOW && filter.match_str == "*") {
      return true;
    }
  }
  return false;
}

bool AccessibilityTreeFormatterBase::MatchesPropertyFilters(
    const std::string& text,
    bool default_result) const {
  return AccessibilityTreeFormatter::MatchesPropertyFilters(
      property_filters_, text, default_result);
}

bool AccessibilityTreeFormatterBase::MatchesNodeFilters(
    const base::DictionaryValue& dict) const {
  return AccessibilityTreeFormatter::MatchesNodeFilters(node_filters_, dict);
}

std::string AccessibilityTreeFormatterBase::FormatCoordinates(
    const base::DictionaryValue& value,
    const std::string& name,
    const std::string& x_name,
    const std::string& y_name) {
  int x, y;
  value.GetInteger(x_name, &x);
  value.GetInteger(y_name, &y);
  return base::StringPrintf("%s=(%d, %d)", name.c_str(), x, y);
}

std::string AccessibilityTreeFormatterBase::FormatRectangle(
    const base::DictionaryValue& value,
    const std::string& name,
    const std::string& left_name,
    const std::string& top_name,
    const std::string& width_name,
    const std::string& height_name) {
  int left, top, width, height;
  value.GetInteger(left_name, &left);
  value.GetInteger(top_name, &top);
  value.GetInteger(width_name, &width);
  value.GetInteger(height_name, &height);
  return base::StringPrintf("%s=(%d, %d, %d, %d)", name.c_str(), left, top,
                            width, height);
}

bool AccessibilityTreeFormatterBase::WriteAttribute(bool include_by_default,
                                                    const std::string& attr,
                                                    std::string* line) {
  if (attr.empty())
    return false;
  if (!MatchesPropertyFilters(attr, include_by_default))
    return false;
  if (!line->empty())
    *line += " ";
  *line += attr;
  return true;
}

void AccessibilityTreeFormatterBase::AddPropertyFilter(
    std::vector<AXPropertyFilter>* property_filters,
    std::string filter,
    AXPropertyFilter::Type type) {
  property_filters->push_back(AXPropertyFilter(filter, type));
}

void AccessibilityTreeFormatterBase::AddDefaultFilters(
    std::vector<AXPropertyFilter>* property_filters) {}

}  // namespace content
