// Copyright 2013 The Flutter 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 "accessibility_bridge.h"

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/executor.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/inspect/cpp/hierarchy.h>
#include <lib/inspect/cpp/inspector.h>
#include <lib/inspect/cpp/reader.h>
#include <lib/sys/cpp/testing/service_directory_provider.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <zircon/status.h>
#include <zircon/types.h>

#include <memory>

#include "flutter/lib/ui/semantics/semantics_node.h"
#include "gtest/gtest.h"

#include "flutter_runner_fakes.h"

namespace flutter_runner_test {

namespace {

void ExpectNodeHasRole(
    const fuchsia::accessibility::semantics::Node& node,
    const std::unordered_map<uint32_t, fuchsia::accessibility::semantics::Role>
        roles_by_node_id) {
  ASSERT_TRUE(node.has_node_id());
  ASSERT_NE(roles_by_node_id.find(node.node_id()), roles_by_node_id.end());
  EXPECT_TRUE(node.has_role());
  EXPECT_EQ(node.role(), roles_by_node_id.at(node.node_id()));
}

}  // namespace

class AccessibilityBridgeTestDelegate {
 public:
  void SetSemanticsEnabled(bool enabled) { enabled_ = enabled; }
  void DispatchSemanticsAction(int32_t node_id,
                               flutter::SemanticsAction action) {
    actions.push_back(std::make_pair(node_id, action));
  }

  bool enabled() { return enabled_; }
  std::vector<std::pair<int32_t, flutter::SemanticsAction>> actions;

 private:
  bool enabled_;
};

class AccessibilityBridgeTest : public testing::Test {
 public:
  AccessibilityBridgeTest()
      : loop_(&kAsyncLoopConfigAttachToCurrentThread),
        services_provider_(loop_.dispatcher()),
        executor_(loop_.dispatcher()) {
    services_provider_.AddService(
        semantics_manager_.GetHandler(loop_.dispatcher()),
        SemanticsManager::Name_);
  }

  void RunLoopUntilIdle() {
    loop_.RunUntilIdle();
    loop_.ResetQuit();
  }

  void RunPromiseToCompletion(fpromise::promise<> promise) {
    bool done = false;
    executor_.schedule_task(
        std::move(promise).and_then([&done]() { done = true; }));
    while (loop_.GetState() == ASYNC_LOOP_RUNNABLE) {
      if (done) {
        loop_.ResetQuit();
        return;
      }

      loop_.Run(zx::deadline_after(zx::duration::infinite()), true);
    }
    loop_.ResetQuit();
  }

 protected:
  void SetUp() override {
    // Connect to SemanticsManager service.
    fidl::InterfaceHandle<fuchsia::accessibility::semantics::SemanticsManager>
        semantics_manager;
    zx_status_t semantics_status =
        services_provider_.service_directory()
            ->Connect<fuchsia::accessibility::semantics::SemanticsManager>(
                semantics_manager.NewRequest());
    if (semantics_status != ZX_OK) {
      FML_LOG(WARNING)
          << "fuchsia::accessibility::semantics::SemanticsManager connection "
             "failed: "
          << zx_status_get_string(semantics_status);
    }

    accessibility_delegate_.actions.clear();
    inspector_ = std::make_unique<inspect::Inspector>();
    flutter_runner::AccessibilityBridge::SetSemanticsEnabledCallback
        set_semantics_enabled_callback = [this](bool enabled) {
          accessibility_delegate_.SetSemanticsEnabled(enabled);
        };
    flutter_runner::AccessibilityBridge::DispatchSemanticsActionCallback
        dispatch_semantics_action_callback =
            [this](int32_t node_id, flutter::SemanticsAction action) {
              accessibility_delegate_.DispatchSemanticsAction(node_id, action);
            };
    auto [view_ref_control, view_ref] = scenic::ViewRefPair::New();
    accessibility_bridge_ =
        std::make_unique<flutter_runner::AccessibilityBridge>(
            std::move(set_semantics_enabled_callback),
            std::move(dispatch_semantics_action_callback),
            std::move(semantics_manager), std::move(view_ref),
            inspector_->GetRoot().CreateChild("test_node"));

    RunLoopUntilIdle();
  }

  void TearDown() override { semantics_manager_.ResetTree(); }

  MockSemanticsManager semantics_manager_;
  AccessibilityBridgeTestDelegate accessibility_delegate_;
  std::unique_ptr<flutter_runner::AccessibilityBridge> accessibility_bridge_;
  // Required to verify inspect metrics.
  std::unique_ptr<inspect::Inspector> inspector_;

 private:
  async::Loop loop_;
  sys::testing::ServiceDirectoryProvider services_provider_;
  // Required to retrieve inspect metrics.
  async::Executor executor_;
};

TEST_F(AccessibilityBridgeTest, RegistersViewRef) {
  EXPECT_TRUE(semantics_manager_.RegisterViewCalled());
}

TEST_F(AccessibilityBridgeTest, EnableDisable) {
  EXPECT_FALSE(accessibility_delegate_.enabled());
  std::unique_ptr<fuchsia::accessibility::semantics::SemanticListener> listener(
      accessibility_bridge_.release());
  listener->OnSemanticsModeChanged(true, nullptr);
  EXPECT_TRUE(accessibility_delegate_.enabled());
}

TEST_F(AccessibilityBridgeTest, RequestAnnounce) {
  accessibility_bridge_->RequestAnnounce("message");
  RunLoopUntilIdle();

  auto& last_events = semantics_manager_.GetLastEvents();
  ASSERT_EQ(last_events.size(), 1u);
  ASSERT_TRUE(last_events[0].is_announce());
  EXPECT_EQ(last_events[0].announce().message(), "message");
}

TEST_F(AccessibilityBridgeTest, PopulatesIsKeyboardKeyAttribute) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsKeyboardKey);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_attributes());
  EXPECT_TRUE(fuchsia_node.attributes().is_keyboard_key());
}

TEST_F(AccessibilityBridgeTest, UpdatesNodeRoles) {
  flutter::SemanticsNodeUpdates updates;

  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.flags |= static_cast<int>(flutter::SemanticsFlags::kIsButton);
  node0.childrenInTraversalOrder = {1, 2, 3, 4, 5, 6, 7, 8};
  node0.childrenInHitTestOrder = {1, 2, 3, 4, 5, 6, 7, 8};
  updates.emplace(0, node0);

  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.flags |= static_cast<int>(flutter::SemanticsFlags::kIsHeader);
  node1.childrenInTraversalOrder = {};
  node1.childrenInHitTestOrder = {};
  updates.emplace(1, node1);

  flutter::SemanticsNode node2;
  node2.id = 2;
  node2.flags |= static_cast<int>(flutter::SemanticsFlags::kIsImage);
  node2.childrenInTraversalOrder = {};
  node2.childrenInHitTestOrder = {};
  updates.emplace(2, node2);

  flutter::SemanticsNode node3;
  node3.id = 3;
  node3.flags |= static_cast<int>(flutter::SemanticsFlags::kIsTextField);
  node3.childrenInTraversalOrder = {};
  node3.childrenInHitTestOrder = {};
  updates.emplace(3, node3);

  flutter::SemanticsNode node4;
  node4.childrenInTraversalOrder = {};
  node4.childrenInHitTestOrder = {};
  node4.id = 4;
  node4.flags |= static_cast<int>(flutter::SemanticsFlags::kIsSlider);
  updates.emplace(4, node4);

  flutter::SemanticsNode node5;
  node5.childrenInTraversalOrder = {};
  node5.childrenInHitTestOrder = {};
  node5.id = 5;
  node5.flags |= static_cast<int>(flutter::SemanticsFlags::kIsLink);
  updates.emplace(5, node5);

  flutter::SemanticsNode node6;
  node6.childrenInTraversalOrder = {};
  node6.childrenInHitTestOrder = {};
  node6.id = 6;
  node6.flags |= static_cast<int>(flutter::SemanticsFlags::kHasCheckedState);
  node6.flags |=
      static_cast<int>(flutter::SemanticsFlags::kIsInMutuallyExclusiveGroup);
  updates.emplace(6, node6);

  flutter::SemanticsNode node7;
  node7.childrenInTraversalOrder = {};
  node7.childrenInHitTestOrder = {};
  node7.id = 7;
  node7.flags |= static_cast<int>(flutter::SemanticsFlags::kHasCheckedState);
  updates.emplace(7, node7);

  flutter::SemanticsNode node8;
  node8.childrenInTraversalOrder = {};
  node8.childrenInHitTestOrder = {};
  node8.id = 8;
  node8.flags |= static_cast<int>(flutter::SemanticsFlags::kHasToggledState);
  updates.emplace(7, node8);

  accessibility_bridge_->AddSemanticsNodeUpdate(std::move(updates), 1.f);
  RunLoopUntilIdle();

  std::unordered_map<uint32_t, fuchsia::accessibility::semantics::Role>
      roles_by_node_id = {
          {0u, fuchsia::accessibility::semantics::Role::BUTTON},
          {1u, fuchsia::accessibility::semantics::Role::HEADER},
          {2u, fuchsia::accessibility::semantics::Role::IMAGE},
          {3u, fuchsia::accessibility::semantics::Role::TEXT_FIELD},
          {4u, fuchsia::accessibility::semantics::Role::SLIDER},
          {5u, fuchsia::accessibility::semantics::Role::LINK},
          {6u, fuchsia::accessibility::semantics::Role::RADIO_BUTTON},
          {7u, fuchsia::accessibility::semantics::Role::CHECK_BOX},
          {8u, fuchsia::accessibility::semantics::Role::TOGGLE_SWITCH}};

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(8u, semantics_manager_.LastUpdatedNodes().size());
  for (const auto& node : semantics_manager_.LastUpdatedNodes()) {
    ExpectNodeHasRole(node, roles_by_node_id);
  }

  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, DeletesChildrenTransitively) {
  // Test that when a node is deleted, so are its transitive children.
  flutter::SemanticsNode node2;
  node2.id = 2;

  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.childrenInTraversalOrder = {2};
  node1.childrenInHitTestOrder = {2};

  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.childrenInTraversalOrder = {1};
  node0.childrenInHitTestOrder = {1};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
          {2, node2},
      },
      1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(3U, semantics_manager_.LastUpdatedNodes().size());
  EXPECT_EQ(0U, semantics_manager_.LastDeletedNodeIds().size());
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());

  // Remove the children
  node0.childrenInTraversalOrder.clear();
  node0.childrenInHitTestOrder.clear();
  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
      },
      1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(1, semantics_manager_.DeleteCount());
  EXPECT_EQ(2, semantics_manager_.UpdateCount());
  EXPECT_EQ(2, semantics_manager_.CommitCount());
  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  ASSERT_EQ(std::vector<uint32_t>({1, 2}),
            semantics_manager_.LastDeletedNodeIds());
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, PopulatesRoleButton) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsButton);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_role());
  EXPECT_EQ(fuchsia_node.role(),
            fuchsia::accessibility::semantics::Role::BUTTON);
}

TEST_F(AccessibilityBridgeTest, PopulatesRoleImage) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsImage);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_role());
  EXPECT_EQ(fuchsia_node.role(),
            fuchsia::accessibility::semantics::Role::IMAGE);
}

TEST_F(AccessibilityBridgeTest, PopulatesRoleSlider) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.actions |= static_cast<int>(flutter::SemanticsAction::kIncrease);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_role());
  EXPECT_EQ(fuchsia_node.role(),
            fuchsia::accessibility::semantics::Role::SLIDER);
}

TEST_F(AccessibilityBridgeTest, PopulatesRoleHeader) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsHeader);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_role());
  EXPECT_EQ(fuchsia_node.role(),
            fuchsia::accessibility::semantics::Role::HEADER);
}

TEST_F(AccessibilityBridgeTest, PopulatesCheckedState) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  // HasCheckedState = true
  // IsChecked = true
  // IsSelected = false
  node0.flags |= static_cast<int>(flutter::SemanticsFlags::kHasCheckedState);
  node0.flags |= static_cast<int>(flutter::SemanticsFlags::kIsChecked);
  node0.value = "value";

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_states());
  const auto& states = fuchsia_node.states();
  EXPECT_TRUE(states.has_checked_state());
  EXPECT_EQ(states.checked_state(),
            fuchsia::accessibility::semantics::CheckedState::CHECKED);
  EXPECT_TRUE(states.has_selected());
  EXPECT_FALSE(states.selected());
  EXPECT_TRUE(states.has_value());
  EXPECT_EQ(states.value(), node0.value);

  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, PopulatesSelectedState) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  // HasCheckedState = false
  // IsChecked = false
  // IsSelected = true
  node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsSelected);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_states());
  const auto& states = fuchsia_node.states();
  EXPECT_TRUE(states.has_checked_state());
  EXPECT_EQ(states.checked_state(),
            fuchsia::accessibility::semantics::CheckedState::NONE);
  EXPECT_TRUE(states.has_selected());
  EXPECT_TRUE(states.selected());

  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, PopulatesToggledState) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.flags |= static_cast<int>(flutter::SemanticsFlags::kHasToggledState);
  node0.flags |= static_cast<int>(flutter::SemanticsFlags::kIsToggled);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(1U, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_states());
  const auto& states = fuchsia_node.states();
  EXPECT_TRUE(states.has_toggled_state());
  EXPECT_EQ(states.toggled_state(),
            fuchsia::accessibility::semantics::ToggledState::ON);

  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, ApplyViewPixelRatioToRoot) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsSelected);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.25f);
  RunLoopUntilIdle();
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_EQ(fuchsia_node.transform().matrix[0], 0.8f);
  EXPECT_EQ(fuchsia_node.transform().matrix[5], 0.8f);
  EXPECT_EQ(fuchsia_node.transform().matrix[10], 1.f);
}

TEST_F(AccessibilityBridgeTest, DoesNotPopulatesHiddenState) {
  // Flutter's notion of a hidden node is different from Fuchsia's hidden node.
  // This test make sures that this state does not get sent.
  flutter::SemanticsNode node0;
  node0.id = 0;
  // HasCheckedState = false
  // IsChecked = false
  // IsSelected = false
  // IsHidden = true
  node0.flags = static_cast<int>(flutter::SemanticsFlags::kIsHidden);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(1u, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.node_id(), static_cast<unsigned int>(node0.id));
  EXPECT_TRUE(fuchsia_node.has_states());
  const auto& states = fuchsia_node.states();
  EXPECT_TRUE(states.has_checked_state());
  EXPECT_EQ(states.checked_state(),
            fuchsia::accessibility::semantics::CheckedState::NONE);
  EXPECT_TRUE(states.has_selected());
  EXPECT_FALSE(states.selected());
  EXPECT_FALSE(states.has_hidden());

  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, PopulatesActions) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.actions |= static_cast<int>(flutter::SemanticsAction::kTap);
  node0.actions |= static_cast<int>(flutter::SemanticsAction::kLongPress);
  node0.actions |= static_cast<int>(flutter::SemanticsAction::kShowOnScreen);
  node0.actions |= static_cast<int>(flutter::SemanticsAction::kIncrease);
  node0.actions |= static_cast<int>(flutter::SemanticsAction::kDecrease);

  accessibility_bridge_->AddSemanticsNodeUpdate({{0, node0}}, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(1u, semantics_manager_.LastUpdatedNodes().size());
  const auto& fuchsia_node = semantics_manager_.LastUpdatedNodes().at(0u);
  EXPECT_EQ(fuchsia_node.actions().size(), 5u);
  EXPECT_EQ(fuchsia_node.actions().at(0u),
            fuchsia::accessibility::semantics::Action::DEFAULT);
  EXPECT_EQ(fuchsia_node.actions().at(1u),
            fuchsia::accessibility::semantics::Action::SECONDARY);
  EXPECT_EQ(fuchsia_node.actions().at(2u),
            fuchsia::accessibility::semantics::Action::SHOW_ON_SCREEN);
  EXPECT_EQ(fuchsia_node.actions().at(3u),
            fuchsia::accessibility::semantics::Action::INCREMENT);
  EXPECT_EQ(fuchsia_node.actions().at(4u),
            fuchsia::accessibility::semantics::Action::DECREMENT);
}

TEST_F(AccessibilityBridgeTest, TruncatesLargeLabel) {
  // Test that labels which are too long are truncated.
  flutter::SemanticsNode node0;
  node0.id = 0;

  flutter::SemanticsNode node1;
  node1.id = 1;

  flutter::SemanticsNode bad_node;
  bad_node.id = 2;
  bad_node.label =
      std::string(fuchsia::accessibility::semantics::MAX_LABEL_SIZE + 1, '2');

  node0.childrenInTraversalOrder = {1, 2};
  node0.childrenInHitTestOrder = {1, 2};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
          {2, bad_node},
      },
      1.f);
  RunLoopUntilIdle();

  // Nothing to delete, but we should have broken
  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(3U, semantics_manager_.LastUpdatedNodes().size());
  auto trimmed_node =
      std::find_if(semantics_manager_.LastUpdatedNodes().begin(),
                   semantics_manager_.LastUpdatedNodes().end(),
                   [id = static_cast<uint32_t>(bad_node.id)](
                       fuchsia::accessibility::semantics::Node const& node) {
                     return node.node_id() == id;
                   });
  ASSERT_NE(trimmed_node, semantics_manager_.LastUpdatedNodes().end());
  ASSERT_TRUE(trimmed_node->has_attributes());
  EXPECT_EQ(
      trimmed_node->attributes().label(),
      std::string(fuchsia::accessibility::semantics::MAX_LABEL_SIZE, '2'));
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, TruncatesLargeToolTip) {
  // Test that tooltips which are too long are truncated.
  flutter::SemanticsNode node0;
  node0.id = 0;

  flutter::SemanticsNode node1;
  node1.id = 1;

  flutter::SemanticsNode bad_node;
  bad_node.id = 2;
  bad_node.tooltip =
      std::string(fuchsia::accessibility::semantics::MAX_LABEL_SIZE + 1, '2');

  node0.childrenInTraversalOrder = {1, 2};
  node0.childrenInHitTestOrder = {1, 2};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
          {2, bad_node},
      },
      1.f);
  RunLoopUntilIdle();

  // Nothing to delete, but we should have broken
  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(3U, semantics_manager_.LastUpdatedNodes().size());
  auto trimmed_node =
      std::find_if(semantics_manager_.LastUpdatedNodes().begin(),
                   semantics_manager_.LastUpdatedNodes().end(),
                   [id = static_cast<uint32_t>(bad_node.id)](
                       fuchsia::accessibility::semantics::Node const& node) {
                     return node.node_id() == id;
                   });
  ASSERT_NE(trimmed_node, semantics_manager_.LastUpdatedNodes().end());
  ASSERT_TRUE(trimmed_node->has_attributes());
  EXPECT_EQ(
      trimmed_node->attributes().secondary_label(),
      std::string(fuchsia::accessibility::semantics::MAX_LABEL_SIZE, '2'));
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, TruncatesLargeValue) {
  // Test that values which are too long are truncated.
  flutter::SemanticsNode node0;
  node0.id = 0;

  flutter::SemanticsNode node1;
  node1.id = 1;

  flutter::SemanticsNode bad_node;
  bad_node.id = 2;
  bad_node.value =
      std::string(fuchsia::accessibility::semantics::MAX_VALUE_SIZE + 1, '2');

  node0.childrenInTraversalOrder = {1, 2};
  node0.childrenInHitTestOrder = {1, 2};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
          {2, bad_node},
      },
      1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(3U, semantics_manager_.LastUpdatedNodes().size());
  auto trimmed_node =
      std::find_if(semantics_manager_.LastUpdatedNodes().begin(),
                   semantics_manager_.LastUpdatedNodes().end(),
                   [id = static_cast<uint32_t>(bad_node.id)](
                       fuchsia::accessibility::semantics::Node const& node) {
                     return node.node_id() == id;
                   });
  ASSERT_NE(trimmed_node, semantics_manager_.LastUpdatedNodes().end());
  ASSERT_TRUE(trimmed_node->has_states());
  EXPECT_EQ(
      trimmed_node->states().value(),
      std::string(fuchsia::accessibility::semantics::MAX_VALUE_SIZE, '2'));
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, SplitsLargeUpdates) {
  // Test that labels which are too long are truncated.
  flutter::SemanticsNode node0;
  node0.id = 0;

  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.label =
      std::string(fuchsia::accessibility::semantics::MAX_LABEL_SIZE, '1');

  flutter::SemanticsNode node2;
  node2.id = 2;
  node2.label = "2";

  flutter::SemanticsNode node3;
  node3.id = 3;
  node3.label = "3";

  flutter::SemanticsNode node4;
  node4.id = 4;
  node4.value =
      std::string(fuchsia::accessibility::semantics::MAX_VALUE_SIZE, '4');

  node0.childrenInTraversalOrder = {1, 2};
  node0.childrenInHitTestOrder = {1, 2};
  node1.childrenInTraversalOrder = {3, 4};
  node1.childrenInHitTestOrder = {3, 4};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
          {2, node2},
          {3, node3},
          {4, node4},
      },
      1.f);
  RunLoopUntilIdle();

  // Nothing to delete, but we should have broken into groups (4, 3, 2), (1, 0)
  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(2, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_EQ(2U, semantics_manager_.LastUpdatedNodes().size());
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, HandlesCycles) {
  // Test that cycles don't cause fatal error.
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.childrenInTraversalOrder.push_back(0);
  node0.childrenInHitTestOrder.push_back(0);
  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
      },
      1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(1, semantics_manager_.UpdateCount());
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());

  node0.childrenInTraversalOrder = {0, 1};
  node0.childrenInHitTestOrder = {0, 1};
  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.childrenInTraversalOrder = {0};
  node1.childrenInHitTestOrder = {0};
  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
      },
      1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_EQ(2, semantics_manager_.UpdateCount());
  EXPECT_EQ(2, semantics_manager_.CommitCount());
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, BatchesLargeMessages) {
  // Tests that messages get batched appropriately.
  flutter::SemanticsNode node0;
  node0.id = 0;

  flutter::SemanticsNodeUpdates update;

  const int32_t child_nodes = 100;
  const int32_t leaf_nodes = 100;
  for (int32_t i = 1; i < child_nodes + 1; i++) {
    flutter::SemanticsNode node;
    node.id = i;
    node0.childrenInTraversalOrder.push_back(i);
    node0.childrenInHitTestOrder.push_back(i);
    for (int32_t j = 0; j < leaf_nodes; j++) {
      flutter::SemanticsNode leaf_node;
      int id = (i * child_nodes) + ((j + 1) * leaf_nodes);
      leaf_node.id = id;
      leaf_node.label = "A relatively simple label";
      node.childrenInTraversalOrder.push_back(id);
      node.childrenInHitTestOrder.push_back(id);
      update.insert(std::make_pair(id, std::move(leaf_node)));
    }
    update.insert(std::make_pair(i, std::move(node)));
  }

  update.insert(std::make_pair(0, std::move(node0)));
  accessibility_bridge_->AddSemanticsNodeUpdate(update, 1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(0, semantics_manager_.DeleteCount());
  EXPECT_TRUE(6 <= semantics_manager_.UpdateCount() &&
              semantics_manager_.UpdateCount() <= 10);
  EXPECT_EQ(1, semantics_manager_.CommitCount());
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());

  int next_update_count = semantics_manager_.UpdateCount() + 1;
  // Remove the children
  node0.childrenInTraversalOrder.clear();
  node0.childrenInHitTestOrder.clear();
  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
      },
      1.f);
  RunLoopUntilIdle();

  EXPECT_EQ(1, semantics_manager_.DeleteCount());
  EXPECT_EQ(next_update_count, semantics_manager_.UpdateCount());
  EXPECT_EQ(2, semantics_manager_.CommitCount());
  EXPECT_FALSE(semantics_manager_.DeleteOverflowed());
  EXPECT_FALSE(semantics_manager_.UpdateOverflowed());
}

TEST_F(AccessibilityBridgeTest, HitTest) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.rect.setLTRB(0, 0, 100, 100);
  node0.flags |= static_cast<int32_t>(flutter::SemanticsFlags::kIsFocusable);

  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.rect.setLTRB(10, 10, 20, 20);
  // Setting platform view id ensures this node is considered focusable.
  node1.platformViewId = 1u;

  flutter::SemanticsNode node2;
  node2.id = 2;
  node2.rect.setLTRB(25, 10, 45, 20);
  // Setting label ensures this node is considered focusable.
  node2.label = "label";

  flutter::SemanticsNode node3;
  node3.id = 3;
  node3.rect.setLTRB(10, 25, 20, 45);
  // Setting actions to a nonzero value ensures this node is considered
  // focusable.
  node3.actions = 1u;

  flutter::SemanticsNode node4;
  node4.id = 4;
  node4.rect.setLTRB(10, 10, 20, 20);
  node4.transform.setTranslate(20, 20, 0);
  node4.flags |= static_cast<int32_t>(flutter::SemanticsFlags::kIsFocusable);

  node0.childrenInTraversalOrder = {1, 2, 3, 4};
  node0.childrenInHitTestOrder = {1, 2, 3, 4};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
          {2, node2},
          {3, node3},
          {4, node4},
      },
      1.f);
  RunLoopUntilIdle();

  uint32_t hit_node_id;
  auto callback = [&hit_node_id](fuchsia::accessibility::semantics::Hit hit) {
    EXPECT_TRUE(hit.has_node_id());
    hit_node_id = hit.node_id();
  };

  // Nodes are:
  // ----------
  // | 1   2  |
  // | 3   4  |
  // ----------

  accessibility_bridge_->HitTest({1, 1}, callback);
  EXPECT_EQ(hit_node_id, 0u);
  accessibility_bridge_->HitTest({15, 15}, callback);
  EXPECT_EQ(hit_node_id, 1u);
  accessibility_bridge_->HitTest({30, 15}, callback);
  EXPECT_EQ(hit_node_id, 2u);
  accessibility_bridge_->HitTest({15, 30}, callback);
  EXPECT_EQ(hit_node_id, 3u);
  accessibility_bridge_->HitTest({30, 30}, callback);
  EXPECT_EQ(hit_node_id, 4u);
}

TEST_F(AccessibilityBridgeTest, HitTestWithPixelRatio) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.rect.setLTRB(0, 0, 100, 100);
  node0.flags |= static_cast<int32_t>(flutter::SemanticsFlags::kIsFocusable);

  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.rect.setLTRB(10, 10, 20, 20);
  // Setting platform view id ensures this node is considered focusable.
  node1.platformViewId = 1u;

  node0.childrenInTraversalOrder = {1};
  node0.childrenInHitTestOrder = {1};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
      },
      // Pick a very small pixel ratio so that a point within the bounds of
      // the node's root-space coordinates will be well outside the "screen"
      // bounds of the node.
      .1f);
  RunLoopUntilIdle();

  uint32_t hit_node_id;
  auto callback = [&hit_node_id](fuchsia::accessibility::semantics::Hit hit) {
    EXPECT_TRUE(hit.has_node_id());
    hit_node_id = hit.node_id();
  };
  accessibility_bridge_->HitTest({15, 15}, callback);
  EXPECT_EQ(hit_node_id, 0u);
}

TEST_F(AccessibilityBridgeTest, HitTestUnfocusableChild) {
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.rect.setLTRB(0, 0, 100, 100);

  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.rect.setLTRB(10, 10, 60, 60);

  flutter::SemanticsNode node2;
  node2.id = 2;
  node2.rect.setLTRB(50, 50, 100, 100);
  node2.flags |= static_cast<int32_t>(flutter::SemanticsFlags::kIsFocusable);

  node0.childrenInTraversalOrder = {1, 2};
  node0.childrenInHitTestOrder = {1, 2};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
          {2, node2},
      },
      1.f);
  RunLoopUntilIdle();

  uint32_t hit_node_id;
  auto callback = [&hit_node_id](fuchsia::accessibility::semantics::Hit hit) {
    EXPECT_TRUE(hit.has_node_id());
    hit_node_id = hit.node_id();
  };

  accessibility_bridge_->HitTest({55, 55}, callback);
  EXPECT_EQ(hit_node_id, 2u);
}

TEST_F(AccessibilityBridgeTest, HitTestOverlapping) {
  // Tests that the first node in hit test order wins, even if a later node
  // would be able to receive the hit.
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.rect.setLTRB(0, 0, 100, 100);
  node0.flags |= static_cast<int32_t>(flutter::SemanticsFlags::kIsFocusable);

  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.rect.setLTRB(0, 0, 100, 100);
  node1.flags |= static_cast<int32_t>(flutter::SemanticsFlags::kIsFocusable);

  flutter::SemanticsNode node2;
  node2.id = 2;
  node2.rect.setLTRB(25, 10, 45, 20);
  node2.flags |= static_cast<int32_t>(flutter::SemanticsFlags::kIsFocusable);

  node0.childrenInTraversalOrder = {1, 2};
  node0.childrenInHitTestOrder = {2, 1};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
          {2, node2},
      },
      1.f);
  RunLoopUntilIdle();

  uint32_t hit_node_id;
  auto callback = [&hit_node_id](fuchsia::accessibility::semantics::Hit hit) {
    EXPECT_TRUE(hit.has_node_id());
    hit_node_id = hit.node_id();
  };

  accessibility_bridge_->HitTest({30, 15}, callback);
  EXPECT_EQ(hit_node_id, 2u);
}

TEST_F(AccessibilityBridgeTest, Actions) {
  flutter::SemanticsNode node0;
  node0.id = 0;

  flutter::SemanticsNode node1;
  node1.id = 1;

  node0.childrenInTraversalOrder = {1};
  node0.childrenInHitTestOrder = {1};

  accessibility_bridge_->AddSemanticsNodeUpdate(
      {
          {0, node0},
          {1, node1},
      },
      1.f);
  RunLoopUntilIdle();

  auto handled_callback = [](bool handled) { EXPECT_TRUE(handled); };
  auto unhandled_callback = [](bool handled) { EXPECT_FALSE(handled); };

  accessibility_bridge_->OnAccessibilityActionRequested(
      0u, fuchsia::accessibility::semantics::Action::DEFAULT, handled_callback);
  EXPECT_EQ(accessibility_delegate_.actions.size(), 1u);
  EXPECT_EQ(accessibility_delegate_.actions.back(),
            std::make_pair(0, flutter::SemanticsAction::kTap));

  accessibility_bridge_->OnAccessibilityActionRequested(
      0u, fuchsia::accessibility::semantics::Action::SECONDARY,
      handled_callback);
  EXPECT_EQ(accessibility_delegate_.actions.size(), 2u);
  EXPECT_EQ(accessibility_delegate_.actions.back(),
            std::make_pair(0, flutter::SemanticsAction::kLongPress));

  accessibility_bridge_->OnAccessibilityActionRequested(
      0u, fuchsia::accessibility::semantics::Action::SET_FOCUS,
      unhandled_callback);
  EXPECT_EQ(accessibility_delegate_.actions.size(), 2u);

  accessibility_bridge_->OnAccessibilityActionRequested(
      0u, fuchsia::accessibility::semantics::Action::SET_VALUE,
      unhandled_callback);
  EXPECT_EQ(accessibility_delegate_.actions.size(), 2u);

  accessibility_bridge_->OnAccessibilityActionRequested(
      0u, fuchsia::accessibility::semantics::Action::SHOW_ON_SCREEN,
      handled_callback);
  EXPECT_EQ(accessibility_delegate_.actions.size(), 3u);
  EXPECT_EQ(accessibility_delegate_.actions.back(),
            std::make_pair(0, flutter::SemanticsAction::kShowOnScreen));

  accessibility_bridge_->OnAccessibilityActionRequested(
      2u, fuchsia::accessibility::semantics::Action::DEFAULT,
      unhandled_callback);
  EXPECT_EQ(accessibility_delegate_.actions.size(), 3u);

  accessibility_bridge_->OnAccessibilityActionRequested(
      0u, fuchsia::accessibility::semantics::Action::INCREMENT,
      handled_callback);
  EXPECT_EQ(accessibility_delegate_.actions.size(), 4u);
  EXPECT_EQ(accessibility_delegate_.actions.back(),
            std::make_pair(0, flutter::SemanticsAction::kIncrease));

  accessibility_bridge_->OnAccessibilityActionRequested(
      0u, fuchsia::accessibility::semantics::Action::DECREMENT,
      handled_callback);
  EXPECT_EQ(accessibility_delegate_.actions.size(), 5u);
  EXPECT_EQ(accessibility_delegate_.actions.back(),
            std::make_pair(0, flutter::SemanticsAction::kDecrease));
}

#if !FLUTTER_RELEASE
TEST_F(AccessibilityBridgeTest, InspectData) {
  flutter::SemanticsNodeUpdates updates;
  flutter::SemanticsNode node0;
  node0.id = 0;
  node0.label = "node0";
  node0.hint = "node0_hint";
  node0.value = "value";
  node0.flags |= static_cast<int>(flutter::SemanticsFlags::kIsButton);
  node0.childrenInTraversalOrder = {1};
  node0.childrenInHitTestOrder = {1};
  node0.rect.setLTRB(0, 0, 100, 100);
  updates.emplace(0, node0);

  flutter::SemanticsNode node1;
  node1.id = 1;
  node1.flags |= static_cast<int>(flutter::SemanticsFlags::kIsHeader);
  node1.childrenInTraversalOrder = {};
  node1.childrenInHitTestOrder = {};
  updates.emplace(1, node1);

  accessibility_bridge_->AddSemanticsNodeUpdate(std::move(updates), 1.f);
  RunLoopUntilIdle();

  fpromise::result<inspect::Hierarchy> hierarchy;
  ASSERT_FALSE(hierarchy.is_ok());
  RunPromiseToCompletion(
      inspect::ReadFromInspector(*inspector_)
          .then([&hierarchy](fpromise::result<inspect::Hierarchy>& result) {
            hierarchy = std::move(result);
          }));
  ASSERT_TRUE(hierarchy.is_ok());

  auto tree_inspect_hierarchy = hierarchy.value().GetByPath({"test_node"});
  ASSERT_NE(tree_inspect_hierarchy, nullptr);
  // TODO(http://fxbug.dev/75841): Rewrite flutter engine accessibility bridge
  // tests using inspect matchers. The checks bellow verify that the tree was
  // built, and that it matches the format of the input tree. This will be
  // updated in the future when test matchers are available to verify individual
  // property values.
  const auto& root = tree_inspect_hierarchy->children();
  ASSERT_EQ(root.size(), 1u);
  EXPECT_EQ(root[0].name(), "semantic_tree_root");
  const auto& child = root[0].children();
  ASSERT_EQ(child.size(), 1u);
  EXPECT_EQ(child[0].name(), "node_1");
}
#endif  // !FLUTTER_RELEASE

}  // namespace flutter_runner_test
