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

#include "content/browser/accessibility/browser_accessibility_fuchsia.h"

#include "base/fuchsia/fuchsia_logging.h"
#include "content/browser/accessibility/browser_accessibility_manager_fuchsia.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_registry.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace content {

using AXRole = ax::mojom::Role;
using FuchsiaRole = fuchsia_accessibility_semantics::Role;

BrowserAccessibilityFuchsia::BrowserAccessibilityFuchsia(
    BrowserAccessibilityManager* manager,
    ui::AXNode* node)
    : BrowserAccessibility(manager, node) {
  platform_node_ =
      static_cast<ui::AXPlatformNodeFuchsia*>(ui::AXPlatformNode::Create(this));
}

ui::AccessibilityBridgeFuchsia*
BrowserAccessibilityFuchsia::GetAccessibilityBridge() const {
  BrowserAccessibilityManagerFuchsia* manager_fuchsia =
      static_cast<BrowserAccessibilityManagerFuchsia*>(manager());
  DCHECK(manager_fuchsia);

  return manager_fuchsia->GetAccessibilityBridge();
}

// static
std::unique_ptr<BrowserAccessibility> BrowserAccessibility::Create(
    BrowserAccessibilityManager* manager,
    ui::AXNode* node) {
  return std::make_unique<BrowserAccessibilityFuchsia>(manager, node);
}

BrowserAccessibilityFuchsia::~BrowserAccessibilityFuchsia() {
  DeleteNode();
  platform_node_->Destroy();
}

uint32_t BrowserAccessibilityFuchsia::GetFuchsiaNodeID() const {
  return static_cast<uint32_t>(GetUniqueId());
}

fuchsia_accessibility_semantics::Node
BrowserAccessibilityFuchsia::ToFuchsiaNodeData() const {
  return {{
      .node_id = GetFuchsiaNodeID(),
      .role = GetFuchsiaRole(),
      .states = GetFuchsiaStates(),
      .attributes = GetFuchsiaAttributes(),
      .actions = GetFuchsiaActions(),
      .child_ids = GetFuchsiaChildIDs(),
      .location = GetFuchsiaLocation(),
      .container_id = GetOffsetContainerOrRootNodeID(),
      .node_to_container_transform = GetFuchsiaTransform(),
  }};
}

void BrowserAccessibilityFuchsia::OnDataChanged() {
  BrowserAccessibility::OnDataChanged();

  // Declare this node as the fuchsia tree root if it's the root of the main
  // frame's tree.
  if (manager()->IsRootFrameManager() &&
      manager()->GetBrowserAccessibilityRoot() == this) {
    ui::AccessibilityBridgeFuchsia* accessibility_bridge =
        GetAccessibilityBridge();
    if (accessibility_bridge)
      accessibility_bridge->SetRootID(GetUniqueId());
  }

  UpdateNode();
}

void BrowserAccessibilityFuchsia::OnLocationChanged() {
  UpdateNode();
}

BrowserAccessibilityFuchsia* ToBrowserAccessibilityFuchsia(
    BrowserAccessibility* obj) {
  return static_cast<BrowserAccessibilityFuchsia*>(obj);
}

std::vector<uint32_t> BrowserAccessibilityFuchsia::GetFuchsiaChildIDs() const {
  std::vector<uint32_t> child_ids;

  // TODO(abrusher): Switch back to using platform children.
  for (const auto* child : AllChildren()) {
    const BrowserAccessibilityFuchsia* fuchsia_child =
        static_cast<const BrowserAccessibilityFuchsia*>(child);
    DCHECK(fuchsia_child);

    child_ids.push_back(fuchsia_child->GetFuchsiaNodeID());
  }

  return child_ids;
}

std::vector<fuchsia_accessibility_semantics::Action>
BrowserAccessibilityFuchsia::GetFuchsiaActions() const {
  std::vector<fuchsia_accessibility_semantics::Action> actions;

  if (HasAction(ax::mojom::Action::kDoDefault) ||
      GetData().GetDefaultActionVerb() != ax::mojom::DefaultActionVerb::kNone) {
    actions.push_back(fuchsia_accessibility_semantics::Action::kDefault);
  }

  if (HasAction(ax::mojom::Action::kFocus))
    actions.push_back(fuchsia_accessibility_semantics::Action::kSetFocus);

  if (HasAction(ax::mojom::Action::kSetValue))
    actions.push_back(fuchsia_accessibility_semantics::Action::kSetValue);

  if (HasAction(ax::mojom::Action::kScrollToMakeVisible)) {
    actions.push_back(fuchsia_accessibility_semantics::Action::kShowOnScreen);
  }

  return actions;
}

fuchsia_accessibility_semantics::Role
BrowserAccessibilityFuchsia::GetFuchsiaRole() const {
  auto role = GetRole();

  switch (role) {
    case AXRole::kButton:
      return FuchsiaRole::kButton;
    case AXRole::kCell:
      return FuchsiaRole::kCell;
    case AXRole::kCheckBox:
      return FuchsiaRole::kCheckBox;
    case AXRole::kColumnHeader:
      return FuchsiaRole::kColumnHeader;
    case AXRole::kGrid:
      return FuchsiaRole::kGrid;
    case AXRole::kHeader:
      return FuchsiaRole::kHeader;
    case AXRole::kImage:
      return FuchsiaRole::kImage;
    case AXRole::kLink:
      return FuchsiaRole::kLink;
    case AXRole::kList:
      return FuchsiaRole::kList;
    case AXRole::kListItem:
      return FuchsiaRole::kListElement;
    case AXRole::kListMarker:
      return FuchsiaRole::kListElementMarker;
    case AXRole::kParagraph:
      return FuchsiaRole::kParagraph;
    case AXRole::kRadioButton:
      return FuchsiaRole::kRadioButton;
    case AXRole::kRowGroup:
      return FuchsiaRole::kRowGroup;
    case AXRole::kSearchBox:
      return FuchsiaRole::kSearchBox;
    case AXRole::kSlider:
      return FuchsiaRole::kSlider;
    case AXRole::kStaticText:
      return FuchsiaRole::kStaticText;
    case AXRole::kTable:
      return FuchsiaRole::kTable;
    case AXRole::kRow:
      return FuchsiaRole::kTableRow;
    case AXRole::kTextField:
      return FuchsiaRole::kTextField;
    case AXRole::kTextFieldWithComboBox:
      return FuchsiaRole::kTextFieldWithComboBox;
    default:
      return FuchsiaRole::kUnknown;
  }
}

fuchsia_accessibility_semantics::States
BrowserAccessibilityFuchsia::GetFuchsiaStates() const {
  fuchsia_accessibility_semantics::States states;

  // Convert checked state.
  if (HasIntAttribute(ax::mojom::IntAttribute::kCheckedState)) {
    ax::mojom::CheckedState ax_state = GetData().GetCheckedState();
    switch (ax_state) {
      case ax::mojom::CheckedState::kNone:
        states.checked_state(
            fuchsia_accessibility_semantics::CheckedState::kNone);
        break;
      case ax::mojom::CheckedState::kTrue:
        states.checked_state(
            fuchsia_accessibility_semantics::CheckedState::kChecked);
        break;
      case ax::mojom::CheckedState::kFalse:
        states.checked_state(
            fuchsia_accessibility_semantics::CheckedState::kUnchecked);
        break;
      case ax::mojom::CheckedState::kMixed:
        states.checked_state(
            fuchsia_accessibility_semantics::CheckedState::kMixed);
        break;
    }
  }

  // Convert selected state.
  // Indicates whether a node has been selected.
  if (GetData().IsSelectable() &&
      HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
    states.selected(GetBoolAttribute(ax::mojom::BoolAttribute::kSelected));
  }

  // Indicates if the node is hidden.
  states.hidden(IsInvisibleOrIgnored());

  // The user entered value of the node, if applicable.
  if (HasStringAttribute(ax::mojom::StringAttribute::kValue)) {
    const std::string& value =
        GetStringAttribute(ax::mojom::StringAttribute::kValue);
    states.value(
        value.substr(0, fuchsia_accessibility_semantics::kMaxLabelSize));
  }

  // The value a range element currently has.
  if (HasFloatAttribute(ax::mojom::FloatAttribute::kValueForRange)) {
    states.range_value(
        GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange));
  }

  // The scroll offsets, if the element is a scrollable container.
  const float x_scroll_offset =
      GetIntAttribute(ax::mojom::IntAttribute::kScrollX);
  const float y_scroll_offset =
      GetIntAttribute(ax::mojom::IntAttribute::kScrollY);
  if (x_scroll_offset || y_scroll_offset)
    states.viewport_offset({{x_scroll_offset, y_scroll_offset}});

  if (IsFocusable())
    states.focusable(true);

  states.has_input_focus(IsFocused());

  return states;
}

fuchsia_accessibility_semantics::Attributes
BrowserAccessibilityFuchsia::GetFuchsiaAttributes() const {
  fuchsia_accessibility_semantics::Attributes attributes;
  if (HasStringAttribute(ax::mojom::StringAttribute::kName)) {
    const std::string& name =
        GetStringAttribute(ax::mojom::StringAttribute::kName);
    attributes.label(
        name.substr(0, fuchsia_accessibility_semantics::kMaxLabelSize));
  }

  if (HasStringAttribute(ax::mojom::StringAttribute::kDescription)) {
    const std::string& description =
        GetStringAttribute(ax::mojom::StringAttribute::kDescription);
    attributes.secondary_label(
        description.substr(0, fuchsia_accessibility_semantics::kMaxLabelSize));
  }

  if (GetData().IsRangeValueSupported()) {
    fuchsia_accessibility_semantics::RangeAttributes range_attributes;
    if (HasFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange)) {
      range_attributes.min_value(
          GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange));
    }
    if (HasFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange)) {
      range_attributes.max_value(
          GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange));
    }
    if (HasFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange)) {
      range_attributes.step_delta(
          GetFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange));
    }
    attributes.range(std::move(range_attributes));
  }

  if (IsTable()) {
    fuchsia_accessibility_semantics::TableAttributes table_attributes;
    auto col_count = GetTableColCount();
    if (col_count)
      table_attributes.number_of_columns(*col_count);

    auto row_count = GetTableRowCount();
    if (row_count)
      table_attributes.number_of_rows(*row_count);

    if (!table_attributes.IsEmpty())
      attributes.table_attributes(std::move(table_attributes));
  }

  if (IsTableRow()) {
    fuchsia_accessibility_semantics::TableRowAttributes table_row_attributes;
    auto row_index = GetTableRowRowIndex();
    if (row_index) {
      table_row_attributes.row_index(*row_index);
      attributes.table_row_attributes(std::move(table_row_attributes));
    }
  }

  if (IsTableCellOrHeader()) {
    fuchsia_accessibility_semantics::TableCellAttributes table_cell_attributes;

    auto col_index = GetTableCellColIndex();
    if (col_index)
      table_cell_attributes.column_index(*col_index);

    auto row_index = GetTableCellRowIndex();
    if (row_index)
      table_cell_attributes.row_index(*row_index);

    auto col_span = GetTableCellColSpan();
    if (col_span)
      table_cell_attributes.column_span(*col_span);

    auto row_span = GetTableCellRowSpan();
    if (row_span)
      table_cell_attributes.row_span(*row_span);

    if (!table_cell_attributes.IsEmpty())
      attributes.table_cell_attributes(std::move(table_cell_attributes));
  }

  if (IsList()) {
    std::optional<int> size = GetSetSize();
    if (size) {
      fuchsia_accessibility_semantics::SetAttributes list_attributes;
      list_attributes.size(*size);
      attributes.list_attributes(std::move(list_attributes));
    }
  }

  if (IsListElement()) {
    std::optional<int> index = GetPosInSet();
    if (index) {
      fuchsia_accessibility_semantics::SetAttributes list_element_attributes;
      list_element_attributes.index(*index);
      attributes.list_element_attributes(std::move(list_element_attributes));
    }
  }

  return attributes;
}

fuchsia_ui_gfx::BoundingBox BrowserAccessibilityFuchsia::GetFuchsiaLocation()
    const {
  const gfx::RectF& bounds = GetLocation();

  return {{
      .min = {{
          .x = bounds.x(),
          .y = bounds.y(),
          .z = 0.0f,
      }},
      .max = {{
          .x = bounds.right(),
          .y = bounds.bottom(),
          .z = 0.0f,
      }},
  }};
}

fuchsia_ui_gfx::Mat4 BrowserAccessibilityFuchsia::GetFuchsiaTransform() const {
  // Get AXNode's explicit transform.
  gfx::Transform transform;
  if (GetData().relative_bounds.transform)
    transform = *GetData().relative_bounds.transform;

  // Convert to fuchsia's transform type.
  std::array<float, 16> mat = {};
  transform.GetColMajorF(mat.data());
  return {{.matrix = mat}};
}

uint32_t BrowserAccessibilityFuchsia::GetOffsetContainerOrRootNodeID() const {
  int offset_container_id = GetData().relative_bounds.offset_container_id;

  BrowserAccessibility* offset_container =
      offset_container_id == -1 ? manager()->GetBrowserAccessibilityRoot()
                                : manager()->GetFromID(offset_container_id);

  BrowserAccessibilityFuchsia* fuchsia_container =
      ToBrowserAccessibilityFuchsia(offset_container);

  // TODO(https://crbug.com/1321935): Remove this check once we understand why
  // we're getting non-existent offset container IDs from blink.
  if (!fuchsia_container) {
    ZX_LOG(ERROR, ZX_OK) << "Node " << GetId()
                         << " references non-existent offset container ID "
                         << offset_container_id;
    return 0;
  }

  return fuchsia_container->GetFuchsiaNodeID();
}

void BrowserAccessibilityFuchsia::UpdateNode() {
  if (!GetAccessibilityBridge())
    return;

  GetAccessibilityBridge()->UpdateNode(ToFuchsiaNodeData());
}

void BrowserAccessibilityFuchsia::DeleteNode() {
  if (!GetAccessibilityBridge())
    return;

  GetAccessibilityBridge()->DeleteNode(GetFuchsiaNodeID());
}

bool BrowserAccessibilityFuchsia::IsList() const {
  return GetRole() == AXRole::kList;
}

bool BrowserAccessibilityFuchsia::IsListElement() const {
  return GetRole() == AXRole::kListItem;
}

bool BrowserAccessibilityFuchsia::AccessibilityPerformAction(
    const ui::AXActionData& action_data) {
  if (action_data.action == ax::mojom::Action::kHitTest) {
    BrowserAccessibilityManager* root_manager =
        manager()->GetManagerForRootFrame();
    DCHECK(root_manager);

    ui::AccessibilityBridgeFuchsia* accessibility_bridge =
        GetAccessibilityBridge();
    if (!accessibility_bridge)
      return false;

    root_manager->HitTest(action_data.target_point, action_data.request_id);
    return true;
  }

  return BrowserAccessibility::AccessibilityPerformAction(action_data);
}

}  // namespace content
