// 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 "flutter/shell/platform/fuchsia/flutter/accessibility_bridge.h"

#include <gtest/gtest.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 <zircon/types.h>

#include <memory>

#include "flutter/lib/ui/semantics/semantics_node.h"
#include "flutter/shell/platform/fuchsia/flutter/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 {
    zx_status_t status = zx::eventpair::create(
        /*flags*/ 0u, &view_ref_control_.reference, &view_ref_.reference);
    EXPECT_EQ(status, ZX_OK);

    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);
            };
    accessibility_bridge_ =
        std::make_unique<flutter_runner::AccessibilityBridge>(
            std::move(set_semantics_enabled_callback),
            std::move(dispatch_semantics_action_callback),
            services_provider_.service_directory(),
            inspector_->GetRoot().CreateChild("test_node"),
            std::move(view_ref_));
    RunLoopUntilIdle();
  }

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

  fuchsia::ui::views::ViewRefControl view_ref_control_;
  fuchsia::ui::views::ViewRef view_ref_;
  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, 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
