// Copyright 2018 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 "cc/input/snap_fling_controller.h"

#include "cc/input/snap_fling_curve.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace test {
namespace {

class MockSnapFlingClient : public SnapFlingClient {
 public:
  MOCK_CONST_METHOD3(GetSnapFlingInfo,
                     bool(const gfx::Vector2dF& natural_displacement,
                          gfx::Vector2dF* initial_offset,
                          gfx::Vector2dF* target_offset));
  MOCK_METHOD0(ScrollEndForSnapFling, void());
  MOCK_METHOD0(RequestAnimationForSnapFling, void());
  MOCK_METHOD1(ScrollByForSnapFling, gfx::Vector2dF(const gfx::Vector2dF&));
};

class MockSnapFlingCurve : public SnapFlingCurve {
 public:
  MockSnapFlingCurve()
      : SnapFlingCurve(gfx::Vector2dF(),
                       gfx::Vector2dF(0, 100),
                       base::TimeTicks()) {}
  MOCK_CONST_METHOD0(IsFinished, bool());
  MOCK_METHOD1(GetScrollDelta, gfx::Vector2dF(base::TimeTicks));
};

}  // namespace

class SnapFlingControllerTest : public testing::Test {
 public:
  SnapFlingControllerTest() {
    controller_ = std::make_unique<SnapFlingController>(&mock_client_);
  }
  void SetCurve(std::unique_ptr<SnapFlingCurve> curve) {
    controller_->SetCurveForTest(std::move(curve));
  }
  void SetActiveState() { controller_->SetActiveStateForTest(); }

 protected:
  testing::StrictMock<MockSnapFlingClient> mock_client_;
  std::unique_ptr<SnapFlingController> controller_;
};

TEST_F(SnapFlingControllerTest, DoesNotFilterGSBWhenIdle) {
  EXPECT_FALSE(controller_->FilterEventForSnap(
      SnapFlingController::GestureScrollType::kBegin));
}

TEST_F(SnapFlingControllerTest, FiltersGSUAndGSEDependingOnState) {
  // Should not filter GSU and GSE if the fling is not active.
  EXPECT_FALSE(controller_->FilterEventForSnap(
      SnapFlingController::GestureScrollType::kUpdate));
  EXPECT_FALSE(controller_->FilterEventForSnap(
      SnapFlingController::GestureScrollType::kEnd));

  // Should filter GSU and GSE if the fling is active.
  SetActiveState();
  EXPECT_TRUE(controller_->FilterEventForSnap(
      SnapFlingController::GestureScrollType::kUpdate));
  EXPECT_TRUE(controller_->FilterEventForSnap(
      SnapFlingController::GestureScrollType::kEnd));
}

TEST_F(SnapFlingControllerTest, CreatesAndAnimatesCurveOnFirstInertialGSU) {
  SnapFlingController::GestureScrollUpdateInfo gsu;
  gsu.delta = gfx::Vector2dF(0, -10);
  gsu.is_in_inertial_phase = true;

  EXPECT_CALL(mock_client_,
              GetSnapFlingInfo(testing::_, testing::_, testing::_))
      .WillOnce(
          testing::DoAll(testing::SetArgPointee<1>(gfx::Vector2dF(0, 0)),
                         testing::SetArgPointee<2>(gfx::Vector2dF(0, 100)),
                         testing::Return(true)));
  EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(1);
  EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(1);
  EXPECT_TRUE(controller_->HandleGestureScrollUpdate(gsu));
  testing::Mock::VerifyAndClearExpectations(&mock_client_);
}

TEST_F(SnapFlingControllerTest, DoesNotHandleNonInertialGSU) {
  SnapFlingController::GestureScrollUpdateInfo gsu;
  gsu.delta = gfx::Vector2dF(0, -10);
  gsu.is_in_inertial_phase = false;

  EXPECT_CALL(mock_client_,
              GetSnapFlingInfo(testing::_, testing::_, testing::_))
      .Times(0);
  EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(0);
  EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(0);
  EXPECT_FALSE(controller_->HandleGestureScrollUpdate(gsu));
  testing::Mock::VerifyAndClearExpectations(&mock_client_);
}

TEST_F(SnapFlingControllerTest, AnimatesTheCurve) {
  std::unique_ptr<MockSnapFlingCurve> mock_curve =
      std::make_unique<MockSnapFlingCurve>();
  MockSnapFlingCurve* curve = mock_curve.get();
  SetCurve(std::move(mock_curve));

  EXPECT_CALL(*curve, IsFinished()).WillOnce(testing::Return(false));
  EXPECT_CALL(*curve, GetScrollDelta(testing::_))
      .WillOnce(testing::Return(gfx::Vector2dF(100, 100)));
  EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(1);
  EXPECT_CALL(mock_client_, ScrollByForSnapFling(gfx::Vector2dF(100, 100)));
  controller_->Animate(base::TimeTicks() + base::TimeDelta::FromSeconds(1));
  testing::Mock::VerifyAndClearExpectations(&mock_client_);
  testing::Mock::VerifyAndClearExpectations(curve);
}

TEST_F(SnapFlingControllerTest, FinishesTheCurve) {
  std::unique_ptr<MockSnapFlingCurve> mock_curve =
      std::make_unique<MockSnapFlingCurve>();
  MockSnapFlingCurve* curve = mock_curve.get();
  SetCurve(std::move(mock_curve));
  EXPECT_CALL(*curve, IsFinished()).WillOnce(testing::Return(true));
  EXPECT_CALL(*curve, GetScrollDelta(testing::_)).Times(0);
  EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(0);
  EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(0);
  EXPECT_CALL(mock_client_, ScrollEndForSnapFling()).Times(1);
  controller_->Animate(base::TimeTicks() + base::TimeDelta::FromSeconds(1));
  testing::Mock::VerifyAndClearExpectations(curve);
  testing::Mock::VerifyAndClearExpectations(&mock_client_);

  EXPECT_CALL(*curve, IsFinished()).Times(0);
  EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(0);
  EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(0);
  EXPECT_CALL(mock_client_, ScrollEndForSnapFling()).Times(0);
  controller_->Animate(base::TimeTicks() + base::TimeDelta::FromSeconds(2));
  testing::Mock::VerifyAndClearExpectations(curve);
  testing::Mock::VerifyAndClearExpectations(&mock_client_);
}

TEST_F(SnapFlingControllerTest, GSBNotFilteredAndResetsStateWhenActive) {
  SetActiveState();
  EXPECT_TRUE(controller_->FilterEventForSnap(
      SnapFlingController::GestureScrollType::kUpdate));

  EXPECT_CALL(mock_client_, ScrollEndForSnapFling()).Times(1);
  EXPECT_FALSE(controller_->FilterEventForSnap(
      SnapFlingController::GestureScrollType::kBegin));
  testing::Mock::VerifyAndClearExpectations(&mock_client_);

  EXPECT_FALSE(controller_->FilterEventForSnap(
      SnapFlingController::GestureScrollType::kUpdate));
}

}  // namespace test
}  // namespace cc
