// Copyright 2019 The Fuchsia 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 <fuchsia/ui/input/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/ui/scenic/cpp/resources.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>

#include <memory>

#include "src/ui/scenic/lib/gfx/engine/engine.h"
#include "src/ui/scenic/lib/gfx/engine/view_tree.h"
#include "src/ui/scenic/lib/input/tests/util.h"
#include "src/ui/scenic/lib/scenic/scenic.h"

// This test exercises focus transfer logic when touch or mouse events are involved.
//
// A pointer DOWN event typically triggers a pair of focus/unfocus events, each sent to a client.
// However, when the DOWN event does not have associated views, then focus should revert to the root
// of a valid focus chain.
//
// The geometry is constrained to a 9x9 display and layer. We need one root session to set up the
// Scene (with no geometry), and two ordinary sessions to each set up its 5x5 View. The spatial
// layout is as follows:
//
// - - - - - - - - -    (invisible) - scene's origin translated to (1,1), relative to display
// - 1 1 1 1 1 - - -    1 - view 1: a 5x5 square, origin coincides with scene origin
// - 1 1 1 1 1 - y -        (z depth is 1 - lower than view 2)
// - 1 1 2 2 2 2 x -    2 - view 2: a 5x5 square, origin translated (2,2) from scene origin
// - 1 1 2 2 2 2 2 -        (z depth is 0 - higher than view 1)
// - 1 1 2 2 2 2 2 -    x - touch/mouse down on view 2: focus transfers to view 2
// - - - 2 2 2 2 2 -    y - touch/mouse down outside of view: focus transfers to scene
// - - - 2 2 2 2 2 -
// - - - - - - - - -
//
// The scene graph has the following topology:
//         scene
//        /     \
//   holder 1   holder 2
//       |        |
//    view 1     view 2
//
// To create this test setup, we perform translation of each holder (a (0,0,1) and (2,2,0)
// translation for each view holder, respectively, within the scene), in addition to translating the
// Rectangle shape within each view's space (a constant (2,2) translation). Setup finishes by
// transferring focus to view 1.
//
// The first (ADD, DOWN) touch sequence, on x, should successfully transfer focus to view 2.
// The second (ADD, DOWN) touch sequence, on y, should successfully transfer focus to the scene.

namespace src_ui_scenic_lib_input_tests {

using A11yPointerEvent = fuchsia::ui::input::accessibility::PointerEvent;
using A11yStreamResponse = fuchsia::ui::input::accessibility::EventHandling;
using fuchsia::ui::input::InputEvent;
using fuchsia::ui::input::PointerEventPhase;
using fuchsia::ui::input::PointerEventType;
using lib_ui_input_tests::InputSystemTest;
using lib_ui_input_tests::PointerCommandGenerator;
using lib_ui_input_tests::PointerMatches;
using lib_ui_input_tests::ResourceGraph;
using lib_ui_input_tests::SessionWrapper;
using scenic_impl::gfx::ViewTree;

// Class fixture for TEST _F. Sets up a 9x9 "display".
class FocusTransferTest : public InputSystemTest {
 protected:
  uint32_t test_display_width_px() const override { return 9; }
  uint32_t test_display_height_px() const override { return 9; }

  // Accessors.
  SessionWrapper* root_session() { return root_session_.get(); }
  ResourceGraph* root_resources() { return root_resources_.get(); }
  SessionWrapper* client_1() { return client_1_.get(); }
  SessionWrapper* client_2() { return client_2_.get(); }

  void ClearEventsInAllSessions() {
    if (root_session_)
      root_session_->events().clear();
    if (client_1_)
      client_1_->events().clear();
    if (client_2_)
      client_2_->events().clear();
  }

 private:
  // Scene setup.
  void SetUp() override {
    InputSystemTest::SetUp();

    auto view_pair_1 = scenic::ViewTokenPair::New();  // root - client 1
    auto view_pair_2 = scenic::ViewTokenPair::New();  // root - client 2

    // Set up a scene with two views.
    auto [root_session, root_resources] = CreateScene();
    {
      scenic::Session* const session = root_session.session();
      scenic::Scene* const scene = &root_resources.scene;

      // Translate the scene.
      scene->SetTranslation(1, 1, 0);

      // Attach the translated view holders.
      scenic::ViewHolder holder_1(session, std::move(view_pair_1.view_holder_token), "holder_1"),
          holder_2(session, std::move(view_pair_2.view_holder_token), "holder_2");

      holder_1.SetViewProperties(k5x5x1);
      holder_2.SetViewProperties(k5x5x1);

      scene->AddChild(holder_1);
      holder_1.SetTranslation(0, 0, 1);  // View 1's origin coincides with Scene's origin.

      scene->AddChild(holder_2);
      holder_2.SetTranslation(2, 2, 0);  // View 2's origin translated (2, 2) wrt Scene's origin.

      RequestToPresent(session);
    }

    // Clients.
    SessionWrapper client_1 = CreateClient("View 1", std::move(view_pair_1.view_token)),
                   client_2 = CreateClient("View 2", std::move(view_pair_2.view_token));

    // Transfer focus to client 1.
    {
      root_session.SetViewKoid(engine()->scene_graph()->view_tree().focus_chain()[0]);
      auto status =
          engine()->scene_graph()->RequestFocusChange(root_session.ViewKoid(), client_1.ViewKoid());
      ASSERT_EQ(status, ViewTree::FocusChangeStatus::kAccept);

      RunLoopUntilIdle();  // Flush out focus events to clients.
    }

    // Transfer ownership to test fixture.
    root_session_ = std::make_unique<SessionWrapper>(std::move(root_session));
    root_resources_ = std::make_unique<ResourceGraph>(std::move(root_resources));
    client_1_ = std::make_unique<SessionWrapper>(std::move(client_1));
    client_2_ = std::make_unique<SessionWrapper>(std::move(client_2));

    ClearEventsInAllSessions();
  }

  void TearDown() override {
    root_resources_ = nullptr;
    root_session_ = nullptr;
    client_1_ = nullptr;
    client_2_ = nullptr;
    InputSystemTest::TearDown();
  }

  std::unique_ptr<SessionWrapper> root_session_;
  std::unique_ptr<ResourceGraph> root_resources_;
  std::unique_ptr<SessionWrapper> client_1_;
  std::unique_ptr<SessionWrapper> client_2_;
};

// Class for testing if turning pointer auto focus off works.
class NoFocusTransferTest : public FocusTransferTest {
 private:
  bool auto_focus_behavior() const override { return false; }
};

// Some tests require the presence of an accessibility listener to trigger pointer interception.
class A11yListener : public fuchsia::ui::input::accessibility::PointerEventListener {
 public:
  A11yListener(scenic_impl::input::InputSystem* input_system) : listener_binding_(this) {
    input_system->RegisterA11yListener(listener_binding_.NewBinding(),
                                       [](bool success) { ASSERT_TRUE(success); });
  }

 private:
  // |fuchsia::ui::input::accessibility::PointerEventListener|
  // Simple response: always reject on MOVE event.
  void OnEvent(A11yPointerEvent event) override {
    if (event.phase() == PointerEventPhase::MOVE) {
      listener_binding_.events().OnStreamHandled(event.device_id(), event.pointer_id(),
                                                 A11yStreamResponse::REJECTED);
    }
  }

  fidl::Binding<fuchsia::ui::input::accessibility::PointerEventListener> listener_binding_;
};

// Normally, focus gets transferred to a valid target on the DOWN phase.
TEST_F(FocusTransferTest, TouchFocusWithValidTarget) {
  // Inject ADD/DOWN on client 2 to trigger focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::TOUCH);
    session->Enqueue(finger.Add(7.5, 3.5));
    session->Enqueue(finger.Down(7.5, 3.5));
  }
  RunLoopUntilIdle();

  // Verify client 1 receives unfocus event.
  {
    const std::vector<InputEvent>& events = client_1()->events();
    ASSERT_EQ(events.size(), 1u);
    EXPECT_TRUE(events[0].is_focus());
    EXPECT_FALSE(events[0].focus().focused);
  }

  // Verify client 2 receives focus event.
  {
    const std::vector<InputEvent>& events = client_2()->events();
    ASSERT_EQ(events.size(), 3u);

    // ADD
    EXPECT_TRUE(events[0].is_pointer());
    EXPECT_TRUE(PointerMatches(events[0].pointer(), 1u, PointerEventPhase::ADD, 4.5, 0.5));

    // FOCUS
    EXPECT_TRUE(events[1].is_focus());
    EXPECT_TRUE(events[1].focus().focused);

    // DOWN
    EXPECT_TRUE(events[2].is_pointer());
    EXPECT_TRUE(PointerMatches(events[2].pointer(), 1u, PointerEventPhase::DOWN, 4.5, 0.5));
  }

  // Verify root session receives nothing.
  {
    const std::vector<InputEvent>& events = root_session()->events();
    EXPECT_EQ(events.size(), 0u);
  }
}

// Sometimes, focus does not have a valid target; instead, transfer focus to the root of the focus
// chain, which is the Scene-creating session in GFX.
TEST_F(FocusTransferTest, TouchFocusWithInvalidTarget) {
  // Inject ADD/DOWN outside of clients to trigger focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::TOUCH);
    session->Enqueue(finger.Add(7.5, 2.5));
    session->Enqueue(finger.Down(7.5, 2.5));
  }
  RunLoopUntilIdle();

  // Verify client 1 receives unfocus event.
  {
    const std::vector<InputEvent>& events = client_1()->events();
    ASSERT_EQ(events.size(), 1u);

    EXPECT_TRUE(events[0].is_focus());
    EXPECT_FALSE(events[0].focus().focused);
  }

  // Verify client 2 receives nothing, since nothing was hit.
  {
    const std::vector<InputEvent>& events = client_2()->events();
    EXPECT_EQ(events.size(), 0u);
  }

  // Verify root session receives focus event, since we revert to root of focus chain.
  {
    const std::vector<InputEvent>& events = root_session()->events();
    ASSERT_EQ(events.size(), 1u);

    EXPECT_TRUE(events[0].is_focus());
    EXPECT_TRUE(events[0].focus().focused);
  }
}

// When a valid but unfocused target (client 2) receives an ADD event and DOWN event, and then the
// scene disconnects, the target receives an unfocus event (where focus=false).
TEST_F(FocusTransferTest, TouchFocusDisconnectSceneAfterDown) {
  // Inject ADD/DOWN on client 2 to trigger focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::TOUCH);
    session->Enqueue(finger.Add(7.5, 3.5));
    session->Enqueue(finger.Down(7.5, 3.5));
  }
  RunLoopUntilIdle();

  ClearEventsInAllSessions();

  // Disconnect scene from compositor.
  {
    scenic::Session* const session = root_session()->session();

    scenic::LayerStack alternate_layer_stack(session);
    root_resources()->compositor.SetLayerStack(alternate_layer_stack);
    RequestToPresent(session);
  }

  // Verify client 2 receives unfocus event.
  {
    const std::vector<InputEvent>& events = client_2()->events();
    ASSERT_EQ(events.size(), 1u);

    // FOCUS
    EXPECT_TRUE(events[0].is_focus());
    EXPECT_FALSE(events[0].focus().focused);
  }

  // Verify client 1 receives nothing.
  {
    const std::vector<InputEvent>& events = client_1()->events();
    EXPECT_EQ(events.size(), 0u);
  }

  // Verify root session receives nothing.
  {
    const std::vector<InputEvent>& events = root_session()->events();
    EXPECT_EQ(events.size(), 0u);
  }
}

// Ensure TouchFocusWithValidTarget works after accessibility rejects the pointer stream.
TEST_F(FocusTransferTest, TouchFocusWithValidTargetAfterA11yRejects) {
  A11yListener a11y_listener(input_system());  // Turn on accessibility interception.
  RunLoopUntilIdle();                          // Ensure FIDL calls get processed.

  // Inject ADD/DOWN on client 2 to trigger delayed focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::TOUCH);
    session->Enqueue(finger.Add(7.5, 3.5));
    session->Enqueue(finger.Down(7.5, 3.5));
  }
  RunLoopUntilIdle();

  // Ordinary clients should not see focus events.
  EXPECT_EQ(client_1()->events().size(), 0u);
  EXPECT_EQ(client_2()->events().size(), 0u);
  EXPECT_EQ(root_session()->events().size(), 0u);

  // Inject MOVE to trigger a11y rejection.
  // Inject ADD/DOWN on client 2 to trigger delayed focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::TOUCH);
    session->Enqueue(finger.Move(7.5, 3.5));
  }
  RunLoopUntilIdle();

  // A11y rejection of MOVE should cause event dispatch to ordinary clients.

  // Verify client 1 receives unfocus event.
  {
    const std::vector<InputEvent>& events = client_1()->events();
    ASSERT_EQ(events.size(), 1u);

    // FOCUS
    EXPECT_TRUE(events[0].is_focus());
    EXPECT_FALSE(events[0].focus().focused);
  }

  // Verify  client 2 receives focus event.
  {
    const std::vector<InputEvent>& events = client_2()->events();
    ASSERT_EQ(events.size(), 4u);

    // ADD
    EXPECT_TRUE(events[0].is_pointer());
    EXPECT_TRUE(PointerMatches(events[0].pointer(), 1u, PointerEventPhase::ADD, 4.5, 0.5));

    // FOCUS
    EXPECT_TRUE(events[1].is_focus());
    EXPECT_TRUE(events[1].focus().focused);

    // DOWN
    EXPECT_TRUE(events[2].is_pointer());
    EXPECT_TRUE(PointerMatches(events[2].pointer(), 1u, PointerEventPhase::DOWN, 4.5, 0.5));

    // MOVE
    EXPECT_TRUE(events[3].is_pointer());
    EXPECT_TRUE(PointerMatches(events[3].pointer(), 1u, PointerEventPhase::MOVE, 4.5, 0.5));
  }

  // Verify root session receives nothing.
  {
    const std::vector<InputEvent>& events = root_session()->events();
    EXPECT_EQ(events.size(), 0u);
  }
}

// Ensure TouchFocusWithInvalidTarget works after accessibility rejects the pointer stream.
TEST_F(FocusTransferTest, TouchFocusWithInvalidTargetAfterA11yRejects) {
  A11yListener a11y_listener(input_system());  // Turn on accessibility interception.
  RunLoopUntilIdle();                          // Ensure FIDL calls get processed.

  // Inject ADD, DOWN, and MOVE (the MOVE triggers a11y rejection).
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::TOUCH);
    session->Enqueue(finger.Add(7, 2));
    session->Enqueue(finger.Down(7, 2));
    session->Enqueue(finger.Move(7, 2));
  }
  RunLoopUntilIdle();

  // A11y rejection of MOVE should cause focus event dispatch to ordinary clients.
  // However, there was no latch on DOWN, so nothing should see pointer events.

  // Verify client 1 receives unfocus event.
  {
    const std::vector<InputEvent>& events = client_1()->events();
    ASSERT_EQ(events.size(), 1u);

    // FOCUS
    EXPECT_TRUE(events[0].is_focus());
    EXPECT_FALSE(events[0].focus().focused);
  }

  // Verify client 2 receives nothing, since nothing was hit.
  {
    const std::vector<InputEvent>& events = client_2()->events();
    EXPECT_EQ(events.size(), 0u);
  }

  // Verify root session receives focus event, since we revert to root of focus chain.
  {
    const std::vector<InputEvent>& events = root_session()->events();
    ASSERT_EQ(events.size(), 1u);

    // FOCUS
    EXPECT_TRUE(events[0].is_focus());
    EXPECT_TRUE(events[0].focus().focused);
  }
}

// Normally, focus gets transferred to a valid target on the DOWN phase.
TEST_F(FocusTransferTest, MouseFocusWithValidTarget) {
  // Inject ADD/DOWN on client 2 to trigger delayed focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::MOUSE);
    session->Enqueue(finger.Move(7.5, 3.5));
    session->Enqueue(finger.Down(7.5, 3.5));
  }
  RunLoopUntilIdle();

  // Verify client 1 receives unfocus event.
  {
    const std::vector<InputEvent>& events = client_1()->events();
    ASSERT_EQ(events.size(), 1u);

    // FOCUS
    EXPECT_TRUE(events[0].is_focus());
    EXPECT_FALSE(events[0].focus().focused);
  }

  // Verify client 2 receives focus event.
  {
    const std::vector<InputEvent>& events = client_2()->events();
    ASSERT_EQ(events.size(), 3u);

    // MOVE
    EXPECT_TRUE(events[0].is_pointer());
    EXPECT_TRUE(PointerMatches(events[0].pointer(), 1u, PointerEventPhase::MOVE, 4.5, 0.5,
                               fuchsia::ui::input::PointerEventType::MOUSE));

    // FOCUS
    EXPECT_TRUE(events[1].is_focus());
    EXPECT_TRUE(events[1].focus().focused);

    // DOWN
    EXPECT_TRUE(events[2].is_pointer());
    EXPECT_TRUE(PointerMatches(events[2].pointer(), 1u, PointerEventPhase::DOWN, 4.5, 0.5,
                               fuchsia::ui::input::PointerEventType::MOUSE));
  }

  // Verify root session receives nothing.
  {
    const std::vector<InputEvent>& events = root_session()->events();
    EXPECT_EQ(events.size(), 0u);
  }
}

// Sometimes, focus does not have a valid target; instead, transfer focus to the root of the focus
// chain, which is the Scene-creating session in GFX.
TEST_F(FocusTransferTest, MouseFocusWithInvalidTarget) {
  // Inject ADD/DOWN outside of clients to trigger focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::MOUSE);
    session->Enqueue(finger.Move(7, 2));
    session->Enqueue(finger.Down(7, 2));
  }
  RunLoopUntilIdle();

  // Verify client 1 receives unfocus event.
  {
    const std::vector<InputEvent>& events = client_1()->events();
    ASSERT_EQ(events.size(), 1u) << "Should receive exactly 1 input event.";

    // FOCUS
    EXPECT_TRUE(events[0].is_focus());
    EXPECT_FALSE(events[0].focus().focused);
  }

  // Verify client 2 receives nothing, since nothing was hit.
  {
    const std::vector<InputEvent>& events = client_2()->events();
    EXPECT_EQ(events.size(), 0u) << "Should receive exactly 0 input events.";
  }

  // Verify root session receives focus event, since we revert to root of focus chain.
  {
    const std::vector<InputEvent>& events = root_session()->events();
    ASSERT_EQ(events.size(), 1u) << "Should receive exactly 1 input event.";

    // FOCUS
    EXPECT_TRUE(events[0].is_focus());
    EXPECT_TRUE(events[0].focus().focused);
  }
}

TEST_F(NoFocusTransferTest, TouchFocusWithValidTarget) {
  // Inject ADD/DOWN on client 2 to trigger focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::TOUCH);
    session->Enqueue(finger.Add(7.5, 3.5));
    session->Enqueue(finger.Down(7.5, 3.5));
  }
  RunLoopUntilIdle();

  // Verify no client receives focus events.
  EXPECT_TRUE(client_1()->events().empty());
  {
    const std::vector<InputEvent>& events = client_2()->events();
    ASSERT_EQ(events.size(), 2u);
    EXPECT_TRUE(events[0].is_pointer());
    EXPECT_TRUE(events[1].is_pointer());
  }
}

TEST_F(NoFocusTransferTest, MouseFocusWithValidTarget) {
  // Inject ADD/DOWN on client 2 and observe no focus dispatch.
  {
    scenic::Session* const session = root_session()->session();

    PointerCommandGenerator finger(root_resources()->compositor.id(), /*device id*/ 1,
                                   /*pointer id*/ 1, PointerEventType::MOUSE);
    session->Enqueue(finger.Move(7.5, 3.5));
    session->Enqueue(finger.Down(7.5, 3.5));
  }
  RunLoopUntilIdle();

  // Verify no client receives focus events.
  EXPECT_TRUE(client_1()->events().empty());
  {
    const std::vector<InputEvent>& events = client_2()->events();
    ASSERT_EQ(events.size(), 2u);
    EXPECT_TRUE(events[0].is_pointer());
    EXPECT_TRUE(events[1].is_pointer());
  }
}

}  // namespace src_ui_scenic_lib_input_tests
