// 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 "cc/animation/worklet_animation.h"

#include <utility>
#include "base/memory/ptr_util.h"
#include "cc/animation/scroll_timeline.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/animation_timelines_test_common.h"
#include "cc/trees/property_tree.h"
#include "testing/gmock/include/gmock/gmock.h"

using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::_;

namespace cc {

namespace {

class MockKeyframeEffect : public KeyframeEffect {
 public:
  MockKeyframeEffect() : KeyframeEffect(0) {}
  MOCK_METHOD1(Tick, void(base::TimeTicks monotonic_time));
};

class WorkletAnimationTest : public AnimationTimelinesTest {
 public:
  WorkletAnimationTest() = default;
  ~WorkletAnimationTest() override = default;

  void AttachWorkletAnimation() {
    client_.RegisterElement(element_id_, ElementListType::ACTIVE);

    worklet_animation_ = WrapRefCounted(
        new WorkletAnimation(1, worklet_animation_id_, "test_name", 1, nullptr,
                             nullptr, true /* controlling instance*/));
    worklet_animation_->AttachElement(element_id_);
    host_->AddAnimationTimeline(timeline_);
    timeline_->AttachAnimation(worklet_animation_);
  }

  scoped_refptr<WorkletAnimation> worklet_animation_;
  WorkletAnimationId worklet_animation_id_{11, 12};
};

class MockScrollTimeline : public ScrollTimeline {
 public:
  MockScrollTimeline()
      : ScrollTimeline(ElementId(),
                       ScrollTimeline::ScrollDown,
                       base::nullopt,
                       base::nullopt,
                       0) {}
  MOCK_CONST_METHOD2(CurrentTime, double(const ScrollTree&, bool));
};

TEST_F(WorkletAnimationTest, NonImplInstanceDoesNotTickKeyframe) {
  std::unique_ptr<MockKeyframeEffect> effect =
      std::make_unique<MockKeyframeEffect>();
  MockKeyframeEffect* mock_effect = effect.get();

  scoped_refptr<WorkletAnimation> worklet_animation =
      WrapRefCounted(new WorkletAnimation(
          1, worklet_animation_id_, "test_name", 1, nullptr, nullptr,
          false /* not impl instance*/, std::move(effect)));

  EXPECT_CALL(*mock_effect, Tick(_)).Times(0);

  MutatorOutputState::AnimationState state(worklet_animation_id_);
  state.local_times.push_back(base::TimeDelta::FromSecondsD(1));
  worklet_animation->SetOutputState(state);
  worklet_animation->Tick(base::TimeTicks());
}

TEST_F(WorkletAnimationTest, LocalTimeIsUsedWhenTicking) {
  AttachWorkletAnimation();

  const float start_opacity = .7f;
  const float end_opacity = .3f;
  const double duration = 1.;

  const float expected_opacity =
      start_opacity + (end_opacity - start_opacity) / 2;
  AddOpacityTransitionToAnimation(worklet_animation_.get(), duration,
                                  start_opacity, end_opacity, true);

  KeyframeModel* keyframe_model =
      worklet_animation_->GetKeyframeModel(TargetProperty::OPACITY);
  // Impl side animation don't need synchronized start time.
  keyframe_model->set_needs_synchronized_start_time(false);

  base::TimeDelta local_time = base::TimeDelta::FromSecondsD(duration / 2);
  MutatorOutputState::AnimationState state(worklet_animation_id_);
  state.local_times.push_back(local_time);
  worklet_animation_->SetOutputState(state);

  worklet_animation_->Tick(base::TimeTicks());

  TestLayer* layer =
      client_.FindTestLayer(element_id_, ElementListType::ACTIVE);
  EXPECT_TRUE(layer->is_property_mutated(TargetProperty::OPACITY));
  client_.ExpectOpacityPropertyMutated(element_id_, ElementListType::ACTIVE,
                                       expected_opacity);
}

TEST_F(WorkletAnimationTest, CurrentTimeCorrectlyUsesScrollTimeline) {
  auto scroll_timeline = std::make_unique<MockScrollTimeline>();
  EXPECT_CALL(*scroll_timeline, CurrentTime(_, _)).WillRepeatedly(Return(1234));
  scoped_refptr<WorkletAnimation> worklet_animation =
      WorkletAnimation::Create(worklet_animation_id_, "test_name", 1,
                               std::move(scroll_timeline), nullptr);

  ScrollTree scroll_tree;
  std::unique_ptr<MutatorInputState> state =
      std::make_unique<MutatorInputState>();
  worklet_animation->UpdateInputState(state.get(), base::TimeTicks::Now(),
                                      scroll_tree, true);
  std::unique_ptr<AnimationWorkletInput> input =
      state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(1234, input->added_and_updated_animations[0].current_time);
}

TEST_F(WorkletAnimationTest,
       CurrentTimeFromRegularTimelineIsOffsetByStartTime) {
  scoped_refptr<WorkletAnimation> worklet_animation = WorkletAnimation::Create(
      worklet_animation_id_, "test_name", 1, nullptr, nullptr);

  base::TimeTicks first_ticks =
      base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111);
  base::TimeTicks second_ticks =
      base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111 + 123.4);
  base::TimeTicks third_ticks =
      base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111 + 246.8);

  ScrollTree scroll_tree;
  std::unique_ptr<MutatorInputState> state =
      std::make_unique<MutatorInputState>();
  worklet_animation->UpdateInputState(state.get(), first_ticks, scroll_tree,
                                      true);
  // First state request sets the start time and thus current time should be 0.
  std::unique_ptr<AnimationWorkletInput> input =
      state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(0, input->added_and_updated_animations[0].current_time);
  state.reset(new MutatorInputState);
  worklet_animation->UpdateInputState(state.get(), second_ticks, scroll_tree,
                                      true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(123.4, input->updated_animations[0].current_time);
  // Should always offset from start time.
  state.reset(new MutatorInputState());
  worklet_animation->UpdateInputState(state.get(), third_ticks, scroll_tree,
                                      true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(246.8, input->updated_animations[0].current_time);
}

// Verifies correctness of current time when playback rate is set on
// initializing the animation and while the animation is playing.
TEST_F(WorkletAnimationTest, DocumentTimelineSetPlaybackRate) {
  const double playback_rate_double = 2;
  const double playback_rate_half = 0.5;
  scoped_refptr<WorkletAnimation> worklet_animation =
      WorkletAnimation::Create(worklet_animation_id_, "test_name",
                               playback_rate_double, nullptr, nullptr);

  base::TimeTicks first_ticks =
      base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111);
  base::TimeTicks second_ticks =
      base::TimeTicks() + base::TimeDelta::FromMillisecondsD(111 + 123.4);
  base::TimeTicks third_ticks =
      base::TimeTicks() +
      base::TimeDelta::FromMillisecondsD(111 + 123.4 + 200.0);

  ScrollTree scroll_tree;
  std::unique_ptr<MutatorInputState> state =
      std::make_unique<MutatorInputState>();
  // Start the animation.
  worklet_animation->UpdateInputState(state.get(), first_ticks, scroll_tree,
                                      true);
  state.reset(new MutatorInputState);

  // Play until second_ticks.
  worklet_animation->UpdateInputState(state.get(), second_ticks, scroll_tree,
                                      true);
  std::unique_ptr<AnimationWorkletInput> input =
      state->TakeWorkletState(worklet_animation_id_.worklet_id);

  // Verify that the current time is updated twice faster than the timeline
  // time.
  EXPECT_EQ(123.4 * playback_rate_double,
            input->updated_animations[0].current_time);

  // Update the playback rate.
  worklet_animation->SetPlaybackRateForTesting(playback_rate_half);
  state.reset(new MutatorInputState());

  // Play until third_ticks.
  worklet_animation->UpdateInputState(state.get(), third_ticks, scroll_tree,
                                      true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);

  // Verify that the current time is updated half as fast as the timeline time.
  EXPECT_EQ(123.4 * playback_rate_double + 200.0 * playback_rate_half,
            input->updated_animations[0].current_time);
}

// This test verifies that worklet animation state is properly updated.
TEST_F(WorkletAnimationTest, UpdateInputStateProducesCorrectState) {
  AttachWorkletAnimation();

  const float start_opacity = .7f;
  const float end_opacity = .3f;
  const double duration = 1.;

  int keyframe_model_id = AddOpacityTransitionToAnimation(
      worklet_animation_.get(), duration, start_opacity, end_opacity, true);

  ScrollTree scroll_tree;
  std::unique_ptr<MutatorInputState> state =
      std::make_unique<MutatorInputState>();

  KeyframeModel* keyframe_model =
      worklet_animation_->GetKeyframeModel(TargetProperty::OPACITY);
  ASSERT_TRUE(keyframe_model);

  base::TimeTicks time;
  worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
  std::unique_ptr<AnimationWorkletInput> input =
      state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(input->added_and_updated_animations.size(), 1u);
  EXPECT_EQ("test_name", input->added_and_updated_animations[0].name);
  EXPECT_EQ(input->updated_animations.size(), 0u);
  EXPECT_EQ(input->removed_animations.size(), 0u);

  // The state of WorkletAnimation is updated to RUNNING after calling
  // UpdateInputState above.
  state.reset(new MutatorInputState());
  time += base::TimeDelta::FromSecondsD(0.1);
  worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(input->added_and_updated_animations.size(), 0u);
  EXPECT_EQ(input->updated_animations.size(), 1u);
  EXPECT_EQ(input->removed_animations.size(), 0u);

  // Operating on individual KeyframeModel doesn't affect the state of
  // WorkletAnimation.
  keyframe_model->SetRunState(KeyframeModel::FINISHED, time);
  state.reset(new MutatorInputState());
  time += base::TimeDelta::FromSecondsD(0.1);
  worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(input->added_and_updated_animations.size(), 0u);
  EXPECT_EQ(input->updated_animations.size(), 1u);
  EXPECT_EQ(input->removed_animations.size(), 0u);

  // WorkletAnimation sets state to REMOVED when JavaScript fires cancel() which
  // leads to RemoveKeyframeModel.
  worklet_animation_->RemoveKeyframeModel(keyframe_model_id);
  worklet_animation_->UpdateState(true, nullptr);
  state.reset(new MutatorInputState());
  worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(input->added_and_updated_animations.size(), 0u);
  EXPECT_EQ(input->updated_animations.size(), 0u);
  EXPECT_EQ(input->removed_animations.size(), 1u);
  EXPECT_EQ(input->removed_animations[0], worklet_animation_id_);
}

// This test verifies that worklet animation gets skipped properly.
TEST_F(WorkletAnimationTest, SkipUnchangedAnimations) {
  AttachWorkletAnimation();

  const float start_opacity = .7f;
  const float end_opacity = .3f;
  const double duration = 1.;

  int keyframe_model_id = AddOpacityTransitionToAnimation(
      worklet_animation_.get(), duration, start_opacity, end_opacity, true);

  ScrollTree scroll_tree;
  std::unique_ptr<MutatorInputState> state =
      std::make_unique<MutatorInputState>();

  base::TimeTicks time;
  worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
  std::unique_ptr<AnimationWorkletInput> input =
      state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(input->added_and_updated_animations.size(), 1u);
  EXPECT_EQ(input->updated_animations.size(), 0u);

  state.reset(new MutatorInputState());
  // No update on the input state if input time stays the same.
  worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_FALSE(input);

  state.reset(new MutatorInputState());
  // Different input time causes the input state to be updated.
  time += base::TimeDelta::FromSecondsD(0.1);
  worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(input->updated_animations.size(), 1u);

  state.reset(new MutatorInputState());
  // Input state gets updated when the worklet animation is to be removed even
  // the input time doesn't change.
  worklet_animation_->RemoveKeyframeModel(keyframe_model_id);
  worklet_animation_->UpdateInputState(state.get(), time, scroll_tree, true);
  input = state->TakeWorkletState(worklet_animation_id_.worklet_id);
  EXPECT_EQ(input->updated_animations.size(), 0u);
  EXPECT_EQ(input->removed_animations.size(), 1u);
}

}  // namespace

}  // namespace cc
