// Copyright 2017 The Chromium 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 "chrome/browser/vr/ui_input_manager.h"

#include <memory>

#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "cc/test/geometry_test_utils.h"
#include "chrome/browser/vr/content_input_delegate.h"
#include "chrome/browser/vr/elements/rect.h"
#include "chrome/browser/vr/elements/ui_element.h"
#include "chrome/browser/vr/model/model.h"
#include "chrome/browser/vr/test/animation_utils.h"
#include "chrome/browser/vr/test/constants.h"
#include "chrome/browser/vr/test/mock_content_input_delegate.h"
#include "chrome/browser/vr/test/ui_test.h"
#include "chrome/browser/vr/ui_scene.h"
#include "chrome/browser/vr/ui_scene_constants.h"
#include "chrome/browser/vr/ui_scene_creator.h"
#include "chrome/browser/vr/ui_unsupported_mode.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/WebKit/public/platform/WebGestureEvent.h"

using ::testing::_;
using ::testing::InSequence;
using ::testing::Mock;
using ::testing::StrictMock;

namespace vr {

constexpr UiInputManager::ButtonState kUp = UiInputManager::ButtonState::UP;
constexpr UiInputManager::ButtonState kDown = UiInputManager::ButtonState::DOWN;

class MockRect : public Rect {
 public:
  MockRect() = default;
  ~MockRect() override = default;

  MOCK_METHOD1(OnHoverEnter, void(const gfx::PointF& position));
  MOCK_METHOD0(OnHoverLeave, void());
  MOCK_METHOD1(OnMove, void(const gfx::PointF& position));
  MOCK_METHOD1(OnButtonDown, void(const gfx::PointF& position));
  MOCK_METHOD1(OnButtonUp, void(const gfx::PointF& position));
  MOCK_METHOD1(OnFocusChanged, void(bool));
  MOCK_METHOD1(OnInputEdited, void(const TextInputInfo&));
  MOCK_METHOD1(OnInputCommitted, void(const TextInputInfo&));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockRect);
};

class MockTextInput : public TextInput {
 public:
  MockTextInput()
      : TextInput(1,
                  base::RepeatingCallback<void(bool)>(),
                  base::RepeatingCallback<void(const TextInputInfo&)>()) {}
  ~MockTextInput() override = default;

  MOCK_METHOD1(OnFocusChanged, void(bool));
  MOCK_METHOD1(OnInputEdited, void(const TextInputInfo&));
  MOCK_METHOD1(OnInputCommitted, void(const TextInputInfo&));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockTextInput);
};

class UiInputManagerTest : public testing::Test {
 public:
  void SetUp() override {
    scene_ = std::make_unique<UiScene>();
    input_manager_ = std::make_unique<UiInputManager>(scene_.get());
  }

  StrictMock<MockRect>* CreateAndAddMockElement(float z_position) {
    auto element = std::make_unique<StrictMock<MockRect>>();
    StrictMock<MockRect>* p_element = element.get();
    element->SetTranslate(0, 0, z_position);
    scene_->AddUiElement(kRoot, std::move(element));
    scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
    return p_element;
  }

  StrictMock<MockTextInput>* CreateAndAddMockInputElement(float z_position) {
    auto element = std::make_unique<StrictMock<MockTextInput>>();
    StrictMock<MockTextInput>* p_element = element.get();
    element->SetTranslate(0, 0, z_position);
    scene_->AddUiElement(kRoot, std::move(element));
    scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
    return p_element;
  }

  void HandleInput(const gfx::Vector3dF& laser_direction,
                   UiInputManager::ButtonState button_state) {
    HandleInput({0, 0, 0}, laser_direction, button_state);
  }

  void HandleInput(const gfx::Point3F& laser_origin,
                   const gfx::Vector3dF& laser_direction,
                   UiInputManager::ButtonState button_state) {
    controller_model_.laser_direction = laser_direction;
    controller_model_.laser_origin = laser_origin;
    controller_model_.touchpad_button_state = button_state;
    input_manager_->HandleInput(MsToTicks(1), controller_model_,
                                &reticle_model_, &gesture_list_);
  }

 protected:
  std::unique_ptr<UiScene> scene_;
  std::unique_ptr<UiInputManager> input_manager_;
  ReticleModel reticle_model_;
  ControllerModel controller_model_;
  GestureList gesture_list_;
  InSequence inSequence;
};

class UiInputManagerContentTest : public UiTest {
 public:
  void SetUp() override {
    UiTest::SetUp();
    CreateScene(kNotInCct, kNotInWebVr);
    input_manager_ = ui_->input_manager();
  }

 protected:
  UiInputManager* input_manager_;
};

TEST_F(UiInputManagerTest, FocusedElement) {
  StrictMock<MockTextInput>* p_element1 = CreateAndAddMockInputElement(-5.f);
  StrictMock<MockTextInput>* p_element2 = CreateAndAddMockInputElement(-5.f);
  TextInputInfo edit(base::ASCIIToUTF16("asdfg"));

  // Focus request triggers OnFocusChanged.
  testing::Sequence s;
  EXPECT_CALL(*p_element1, OnFocusChanged(true)).InSequence(s);
  input_manager_->RequestFocus(p_element1->id());

  // Edit goes to focused element.
  EXPECT_CALL(*p_element1, OnInputEdited(edit)).InSequence(s);
  input_manager_->OnInputEdited(edit);

  // Commit goes to focused element.
  EXPECT_CALL(*p_element1, OnInputCommitted(edit)).InSequence(s);
  input_manager_->OnInputCommitted(edit);

  // Focus on a different element triggers OnFocusChanged.
  EXPECT_CALL(*p_element1, OnFocusChanged(false)).InSequence(s);
  EXPECT_CALL(*p_element2, OnFocusChanged(true)).InSequence(s);
  input_manager_->RequestFocus(p_element2->id());
}

// Verify that a focusable child clears focus off its parent. Note that the
// child isn't any different from other elements in that it should also steal
// focus from its parent.
TEST_F(UiInputManagerTest, FocusableChildStealsFocus) {
  StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f);

  auto child = std::make_unique<StrictMock<MockRect>>();
  auto* p_child = child.get();
  child->set_hit_testable(true);
  child->set_focusable(true);
  p_element->AddChild(std::move(child));
  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);

  // Focus element.
  testing::Sequence s;
  EXPECT_CALL(*p_element, OnFocusChanged(true)).InSequence(s);
  input_manager_->RequestFocus(p_element->id());

  // Focus child.
  EXPECT_CALL(*p_child, OnHoverEnter(_)).InSequence(s);
  EXPECT_CALL(*p_child, OnButtonDown(_)).InSequence(s);
  HandleInput(kForwardVector, kDown);
  EXPECT_CALL(*p_child, OnMove(_)).InSequence(s);
  EXPECT_CALL(*p_child, OnButtonUp(_)).InSequence(s);
  EXPECT_CALL(*p_element, OnFocusChanged(false)).InSequence(s);
  HandleInput(kForwardVector, kUp);
}

// Verify that a non-focusable child does not clear focus off its parent.
TEST_F(UiInputManagerTest, NonFocusableChildDoestNotStealFocus) {
  StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f);

  auto child = std::make_unique<StrictMock<MockRect>>();
  auto* p_child = child.get();
  child->set_hit_testable(true);
  child->set_focusable(false);
  p_element->AddChild(std::move(child));
  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);

  // Focus element.
  testing::Sequence s;
  EXPECT_CALL(*p_element, OnFocusChanged(true)).InSequence(s);
  input_manager_->RequestFocus(p_element->id());

  // Focus child.
  EXPECT_CALL(*p_child, OnHoverEnter(_)).InSequence(s);
  EXPECT_CALL(*p_child, OnButtonDown(_)).InSequence(s);
  EXPECT_CALL(*p_element, OnFocusChanged(false)).Times(0).InSequence(s);
  HandleInput(kForwardVector, kDown);
}

TEST_F(UiInputManagerTest, ReticleRenderTarget) {
  auto element = std::make_unique<Rect>();
  UiElement* p_element = element.get();
  element->SetTranslate(0, 0, -1.f);
  scene_->AddUiElement(kRoot, std::move(element));
  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);

  ControllerModel controller_model;
  controller_model.laser_direction = kBackwardVector;
  controller_model.laser_origin = {0, 0, 0};
  controller_model.touchpad_button_state = kUp;
  ReticleModel reticle_model;
  GestureList gesture_list;

  input_manager_->HandleInput(MsToTicks(1), controller_model, &reticle_model,
                              &gesture_list);
  EXPECT_EQ(0, reticle_model.target_element_id);

  controller_model.laser_direction = kForwardVector;
  input_manager_->HandleInput(MsToTicks(1), controller_model, &reticle_model,
                              &gesture_list);
  EXPECT_EQ(p_element->id(), reticle_model.target_element_id);
  EXPECT_NEAR(-1.0, reticle_model.target_point.z(), kEpsilon);
}

// Test hover and click by toggling button state, and directing the controller
// either directly at (forward) or directly away from (backward) a test element.
// Verify mock expectations along the way to make failures easier to track.
TEST_F(UiInputManagerTest, HoverClick) {
  StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f);

  // Move over the test element.
  EXPECT_CALL(*p_element, OnHoverEnter(_));
  HandleInput(kForwardVector, kUp);
  EXPECT_CALL(*p_element, OnMove(_));
  HandleInput(kForwardVector, kUp);
  Mock::VerifyAndClearExpectations(p_element);

  // Press the button while on the element.
  EXPECT_CALL(*p_element, OnMove(_));
  EXPECT_CALL(*p_element, OnButtonDown(_));
  HandleInput(kForwardVector, kDown);
  Mock::VerifyAndClearExpectations(p_element);

  // Release the button while on the element.
  EXPECT_CALL(*p_element, OnMove(_));
  EXPECT_CALL(*p_element, OnButtonUp(_));
  HandleInput(kForwardVector, kUp);
  Mock::VerifyAndClearExpectations(p_element);

  // Move off of the element.
  EXPECT_CALL(*p_element, OnHoverLeave());
  HandleInput(kBackwardVector, kUp);
  Mock::VerifyAndClearExpectations(p_element);

  // Press while not on the element, move over the element, move away, then
  // release. The element should receive hover events.
  HandleInput(kBackwardVector, kDown);
  EXPECT_CALL(*p_element, OnHoverEnter(_));
  HandleInput(kForwardVector, kDown);
  EXPECT_CALL(*p_element, OnHoverLeave());
  HandleInput(kBackwardVector, kUp);
  Mock::VerifyAndClearExpectations(p_element);

  // Press on an element, move away, then release.
  EXPECT_CALL(*p_element, OnHoverEnter(_));
  EXPECT_CALL(*p_element, OnButtonDown(_));
  HandleInput(kForwardVector, kDown);
  EXPECT_CALL(*p_element, OnHoverLeave());
  HandleInput(kBackwardVector, kDown);
  Mock::VerifyAndClearExpectations(p_element);
  EXPECT_CALL(*p_element, OnButtonUp(_));
  HandleInput(kBackwardVector, kUp);
  Mock::VerifyAndClearExpectations(p_element);
}

// Test pressing the button while on an element, moving to another element, and
// releasing the button. Upon release, the previous element should see its click
// and hover states cleared, and the new element should see a hover.
TEST_F(UiInputManagerTest, ReleaseButtonOnAnotherElement) {
  StrictMock<MockRect>* p_front_element = CreateAndAddMockElement(-5.f);
  StrictMock<MockRect>* p_back_element = CreateAndAddMockElement(5.f);

  // TODO(ymalik): We should test verify that the functions called on the
  // element are in the element's local coordinate space, but that would require
  // writing a matcher for gfx::Point3F.
  // Press on an element, move away, then release.
  EXPECT_CALL(*p_front_element, OnHoverEnter(_));
  EXPECT_CALL(*p_front_element, OnButtonDown(_));
  HandleInput(kForwardVector, kDown);
  EXPECT_CALL(*p_front_element, OnHoverLeave());
  EXPECT_CALL(*p_back_element, OnHoverEnter(_));
  HandleInput(kBackwardVector, kDown);
  EXPECT_CALL(*p_back_element, OnMove(_));
  EXPECT_CALL(*p_front_element, OnButtonUp(_));
  HandleInput(kBackwardVector, kUp);
  EXPECT_CALL(*p_back_element, OnHoverLeave());
  EXPECT_CALL(*p_front_element, OnHoverEnter(_));
  HandleInput(kForwardVector, kUp);
}

// Test that input is tolerant of disappearing elements.
TEST_F(UiInputManagerTest, ElementDeletion) {
  StrictMock<MockRect>* p_element = CreateAndAddMockElement(-5.f);

  // Hover on an element.
  EXPECT_CALL(*p_element, OnHoverEnter(_));
  HandleInput(kForwardVector, kUp);

  // Remove and retain the element from the scene, and ensure that it receives
  // no extraneous input.
  auto deleted_element = scene_->RemoveUiElement(p_element->id());
  HandleInput(kBackwardVector, kUp);
  Mock::VerifyAndClearExpectations(p_element);

  // Re-add the element to the scene, and press on it to lock it for input.
  scene_->AddUiElement(kRoot, std::move(deleted_element));
  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);
  EXPECT_CALL(*p_element, OnHoverEnter(_));
  EXPECT_CALL(*p_element, OnButtonDown(_));
  HandleInput(kForwardVector, kDown);

  // Remove the element again, move off the element, and release to ensure that
  // input isn't delivered to an input-locked element that's been deleted from
  // the scene.
  scene_->RemoveUiElement(p_element->id());
  HandleInput(kBackwardVector, kDown);
  HandleInput(kBackwardVector, kUp);
  Mock::VerifyAndClearExpectations(p_element);
}

// This ensures that the input manager can support both the strategy of hit
// testing along the laser's ray as well as the ray from the world origin to a
// point far along the laser.
TEST_F(UiInputManagerTest, HitTestStrategy) {
  auto element = std::make_unique<Rect>();
  auto* p_element = element.get();
  element->SetTranslate(0, 0, -2.5);
  element->SetSize(1000.0f, 1000.0f);
  scene_->AddUiElement(kRoot, std::move(element));
  scene_->OnBeginFrame(base::TimeTicks(), kStartHeadPose);

  gfx::Point3F center;
  p_element->world_space_transform().TransformPoint(&center);
  gfx::Point3F laser_origin(0.5, -0.5, 0.0);

  HandleInput(laser_origin, center - laser_origin, kDown);

  ASSERT_NE(0, reticle_model_.target_element_id);
  EXPECT_EQ(p_element->id(), reticle_model_.target_element_id);
  EXPECT_POINT3F_EQ(gfx::Point3F(-0.45f, 0.45f, -2.5f),
                    reticle_model_.target_point);

  input_manager_->set_hit_test_strategy(
      UiInputManager::PROJECT_TO_LASER_ORIGIN_FOR_TEST);

  HandleInput(laser_origin, center - laser_origin, kDown);

  ASSERT_NE(0, reticle_model_.target_element_id);
  EXPECT_EQ(p_element->id(), reticle_model_.target_element_id);
  EXPECT_POINT3F_EQ(gfx::Point3F(0.0f, 0.0, -2.5f),
                    reticle_model_.target_point);
}

TEST_F(UiInputManagerContentTest, NoMouseMovesDuringClick) {
  EXPECT_TRUE(RunFor(MsToDelta(500)));
  // It would be nice if the controller weren't platform specific and we could
  // mock out the underlying sensor data. For now, we will hallucinate
  // parameters to HandleInput.
  UiElement* content_quad =
      scene_->GetUiElementByName(UiElementName::kContentQuad);
  gfx::Point3F content_quad_center;
  content_quad->world_space_transform().TransformPoint(&content_quad_center);
  gfx::Point3F origin;

  ControllerModel controller_model;
  controller_model.laser_direction = content_quad_center - origin;
  controller_model.laser_origin = origin;
  controller_model.touchpad_button_state = UiInputManager::ButtonState::DOWN;
  ReticleModel reticle_model;
  GestureList gesture_list;
  input_manager_->HandleInput(MsToTicks(1), controller_model, &reticle_model,
                              &gesture_list);

  // We should have hit the content quad if our math was correct.
  ASSERT_NE(0, reticle_model.target_element_id);
  EXPECT_EQ(content_quad->id(), reticle_model.target_element_id);

  // Unless we suppress content move events during clicks, this will cause us to
  // call OnContentMove on the delegate. We should do this suppression, so we
  // set the expected number of calls to zero.
  EXPECT_CALL(*content_input_delegate_, OnContentMove(testing::_)).Times(0);

  input_manager_->HandleInput(MsToTicks(1), controller_model, &reticle_model,
                              &gesture_list);
}

TEST_F(UiInputManagerContentTest, ExitPromptHitTesting) {
  model_->active_modal_prompt_type = kModalPromptTypeExitVRForSiteInfo;
  EXPECT_TRUE(RunFor(MsToDelta(500)));

  UiElement* exit_prompt =
      scene_->GetUiElementByName(UiElementName::kExitPrompt);
  gfx::Point3F exit_prompt_center;
  exit_prompt->world_space_transform().TransformPoint(&exit_prompt_center);
  gfx::Point3F origin;

  ControllerModel controller_model;
  controller_model.laser_direction = exit_prompt_center - origin;
  controller_model.laser_origin = origin;
  controller_model.touchpad_button_state = UiInputManager::ButtonState::DOWN;
  ReticleModel reticle_model;
  GestureList gesture_list;
  input_manager_->HandleInput(MsToTicks(1), controller_model, &reticle_model,
                              &gesture_list);

  // We should have hit the exit prompt if our math was correct.
  ASSERT_NE(0, reticle_model.target_element_id);
  EXPECT_EQ(exit_prompt->id(), reticle_model.target_element_id);
}

TEST_F(UiInputManagerContentTest, AudioPermissionPromptHitTesting) {
  model_->active_modal_prompt_type =
      kModalPromptTypeExitVRForVoiceSearchRecordAudioOsPermission;
  EXPECT_TRUE(RunFor(MsToDelta(500)));

  UiElement* url_bar = scene_->GetUiElementByName(UiElementName::kUrlBar);
  gfx::Point3F url_bar_center;
  url_bar->world_space_transform().TransformPoint(&url_bar_center);
  gfx::Point3F origin;

  ControllerModel controller_model;
  controller_model.laser_direction = url_bar_center - origin;
  controller_model.laser_origin = origin;
  controller_model.touchpad_button_state = UiInputManager::ButtonState::DOWN;
  ReticleModel reticle_model;
  GestureList gesture_list;
  input_manager_->HandleInput(MsToTicks(1), controller_model, &reticle_model,
                              &gesture_list);

  // Even if the reticle is over the URL bar, the backplane should be in front
  // and should be hit.
  ASSERT_NE(0, reticle_model.target_element_id);
  EXPECT_EQ(scene_->GetUiElementByName(kAudioPermissionPromptBackplane)->id(),
            reticle_model.target_element_id);
}

TEST_F(UiInputManagerContentTest, TreeVsZOrder) {
  // It would be nice if the controller weren't platform specific and we could
  // mock out the underlying sensor data. For now, we will hallucinate
  // parameters to HandleInput.
  UiElement* content_quad =
      scene_->GetUiElementByName(UiElementName::kContentQuad);
  gfx::Point3F content_quad_center;
  content_quad->world_space_transform().TransformPoint(&content_quad_center);
  gfx::Point3F origin;

  ControllerModel controller_model;
  controller_model.laser_direction = content_quad_center - origin;
  controller_model.laser_origin = origin;
  controller_model.touchpad_button_state = UiInputManager::ButtonState::DOWN;
  ReticleModel reticle_model;
  GestureList gesture_list;
  input_manager_->HandleInput(MsToTicks(1), controller_model, &reticle_model,
                              &gesture_list);

  // We should have hit the content quad if our math was correct.
  ASSERT_NE(0, reticle_model.target_element_id);
  EXPECT_EQ(content_quad->id(), reticle_model.target_element_id);

  // We will now move the content quad behind the backplane.
  content_quad->SetTranslate(0, 0, -1.0);
  OnBeginFrame();

  input_manager_->HandleInput(MsToTicks(1), controller_model, &reticle_model,
                              &gesture_list);

  // We should have hit the content quad even though, geometrically, it stacks
  // behind the backplane.
  ASSERT_NE(0, reticle_model.target_element_id);
  EXPECT_EQ(content_quad->id(), reticle_model.target_element_id);
}

}  // namespace vr
