// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <tuple>

#include "base/compiler_specific.h"
#include "build/build_config.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_tree.h"

// The purpose of this script is to fuzz code that parses
// table-like structures. As a result, we want to generate
// accessibility trees that contain lots of table-related
// roles.
//
// We also bias towards cells and rows so that we end up
// with more of those overall.
ax::mojom::Role GetInterestingTableRole(unsigned char byte) {
  switch (byte % 16) {
    default:
    case 0:
    case 1:
    case 2:
    case 3:
      return ax::mojom::Role::kCell;
    case 4:
    case 5:
      return ax::mojom::Role::kRow;
    case 6:
      return ax::mojom::Role::kTable;
    case 7:
      return ax::mojom::Role::kGrid;
    case 8:
      return ax::mojom::Role::kColumnHeader;
    case 9:
      return ax::mojom::Role::kRowHeader;
    case 10:
      return ax::mojom::Role::kGenericContainer;
    case 11:
      return ax::mojom::Role::kNone;
    case 12:
      return ax::mojom::Role::kLayoutTable;
    case 13:
      return ax::mojom::Role::kLayoutTableCell;
    case 14:
      return ax::mojom::Role::kLayoutTableRow;
    case 15:
      return ax::mojom::Role::kMain;
  }
}

// We want some of the nodes in the accessibility tree to have
// table-related attributes.
ax::mojom::IntAttribute GetInterestingTableAttribute(unsigned char byte) {
  switch (byte % 10) {
    case 0:
    default:
      return ax::mojom::IntAttribute::kTableCellRowIndex;
    case 1:
      return ax::mojom::IntAttribute::kTableCellColumnIndex;
    case 2:
      return ax::mojom::IntAttribute::kTableRowCount;
    case 3:
      return ax::mojom::IntAttribute::kTableColumnCount;
    case 4:
      return ax::mojom::IntAttribute::kAriaRowCount;
    case 5:
      return ax::mojom::IntAttribute::kAriaColumnCount;
    case 6:
      return ax::mojom::IntAttribute::kTableCellRowSpan;
    case 7:
      return ax::mojom::IntAttribute::kTableCellColumnSpan;
    case 8:
      return ax::mojom::IntAttribute::kAriaCellRowIndex;
    case 9:
      return ax::mojom::IntAttribute::kAriaCellColumnIndex;
  }
}

// Call all of the table-related APIs on an accessibility node.
// These will be no-ops if the node is not part of a complete
// table. We don't care about any of the results, we just want
// to make sure none of these crash or hang.
void TestTableAPIs(const ui::AXNode* node) {
  std::ignore = node->IsTable();
  std::ignore = node->GetTableColCount();
  std::ignore = node->GetTableRowCount();
  std::ignore = node->GetTableAriaColCount();
  std::ignore = node->GetTableAriaRowCount();
  std::ignore = node->GetTableCellCount();
  std::ignore = node->GetTableCaption();
  for (int i = 0; i < 8; i++)
    std::ignore = node->GetTableCellFromIndex(i);
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      std::ignore = node->GetTableCellFromCoords(i, j);
  // Note: some of the APIs return IDs - we don't care what's
  // returned, we just want to make sure these APIs don't
  // crash. Normally |ids| is an out argument only, but
  // there's no reason we shouldn't be able to pass a vector
  // that was previously used by another call.
  std::vector<ui::AXNodeID> ids;
  for (int i = 0; i < 3; i++) {
    std::vector<ui::AXNodeID> col_header_node_ids =
        node->GetTableColHeaderNodeIds(i);
    ids.insert(ids.end(), col_header_node_ids.begin(),
               col_header_node_ids.end());

    std::vector<ui::AXNodeID> row_header_node_ids =
        node->GetTableRowHeaderNodeIds(i);
    ids.insert(ids.end(), row_header_node_ids.begin(),
               row_header_node_ids.end());
  }
  std::vector<ui::AXNodeID> unique_cell_ids = node->GetTableUniqueCellIds();
  ids.insert(ids.end(), unique_cell_ids.begin(), unique_cell_ids.end());

  std::ignore = node->IsTableRow();
  std::ignore = node->GetTableRowRowIndex();
#if BUILDFLAG(IS_APPLE)
  std::ignore = node->IsTableColumn();
  std::ignore = node->GetTableColColIndex();
#endif
  std::ignore = node->IsTableCellOrHeader();
  std::ignore = node->GetTableCellIndex();
  std::ignore = node->GetTableCellColIndex();
  std::ignore = node->GetTableCellRowIndex();
  std::ignore = node->GetTableCellColSpan();
  std::ignore = node->GetTableCellRowSpan();
  std::ignore = node->GetTableCellAriaColIndex();
  std::ignore = node->GetTableCellAriaRowIndex();
  std::vector<ui::AXNodeID> cell_col_header_node_ids =
      node->GetTableCellColHeaderNodeIds();
  ids.insert(ids.end(), cell_col_header_node_ids.begin(),
             cell_col_header_node_ids.end());
  std::vector<ui::AXNodeID> cell_row_header_node_ids =
      node->GetTableCellRowHeaderNodeIds();
  ids.insert(ids.end(), cell_row_header_node_ids.begin(),
             cell_row_header_node_ids.end());
  std::vector<ui::AXNode*> headers;
  node->GetTableCellColHeaders(&headers);
  node->GetTableCellRowHeaders(&headers);

  for (const ui::AXNode* child : node->children()) {
    TestTableAPIs(child);
  }
}

// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size) {
  ui::AXTreeUpdate initial_state;
  initial_state.root_id = 1;
  size_t i = 0;

  // The root of the accessibility tree.
  ui::AXNodeData root;
  root.id = 1;
  if (i < size)
    root.role = GetInterestingTableRole(UNSAFE_TODO(data[i++]));
  root.child_ids.push_back(2);
  initial_state.nodes.push_back(root);

  // Force the next node of the accessibility tree to be a table,
  // and give it no attributes but a few children.
  ui::AXNodeData table;
  table.id = 2;
  table.role = ax::mojom::Role::kTable;
  if (i < size) {
    size_t child_count = UNSAFE_TODO(data[i++]) % 8;
    for (size_t j = 0; j < child_count && i < size; j++)
      table.child_ids.push_back(3 + UNSAFE_TODO(data[i++]) % 32);
  }
  initial_state.nodes.push_back(table);

  // Create more accessibility nodes that might result in a table.
  int next_id = 3;
  while (i < size) {
    ui::AXNodeData node;
    node.id = next_id++;
    if (i < size)
      node.role = GetInterestingTableRole(UNSAFE_TODO(data[i++]));
    if (i < size) {
      int attr_count = UNSAFE_TODO(data[i++]) % 6;
      for (int j = 0; j < attr_count && i + 1 < size; j++) {
        unsigned char attr = UNSAFE_TODO(data[i++]);
        int32_t value = static_cast<int32_t>(UNSAFE_TODO(data[i++])) - 2;
        node.AddIntAttribute(GetInterestingTableAttribute(attr), value);
      }
    }
    if (i < size) {
      size_t child_count = UNSAFE_TODO(data[i++]) % 8;
      for (size_t j = 0; j < child_count && i < size; j++)
        node.child_ids.push_back(4 + UNSAFE_TODO(data[i++]) % 32);
    }
    initial_state.nodes.push_back(node);
  }

  // Run with --v=1 to aid in debugging a specific crash.
  VLOG(1) << "Input accessibility tree:\n" << initial_state.ToString();

  ui::AXTree tree;
  if (tree.Unserialize(initial_state))
    TestTableAPIs(tree.root());

  return 0;
}
