// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/cssom/length_value.h"
#include "cobalt/cssom/number_value.h"
#include "cobalt/cssom/property_definitions.h"
#include "cobalt/cssom/rgba_color_value.h"
#include "cobalt/web_animations/keyframe_effect_read_only.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace web_animations {

TEST(KeyframeEffectReadOnlyDataTest, IsPropertyAnimated) {
  std::vector<Keyframe::Data> keyframes;

  Keyframe::Data frame1(0.0);
  frame1.AddPropertyValue(cssom::kColorProperty,
                          new cssom::RGBAColorValue(0, 100, 0, 100));
  keyframes.push_back(frame1);

  Keyframe::Data frame2(0.5);
  frame2.AddPropertyValue(cssom::kOpacityProperty, new cssom::NumberValue(0.5));
  keyframes.push_back(frame2);

  Keyframe::Data frame3(1.0);
  frame3.AddPropertyValue(cssom::kBackgroundColorProperty,
                          new cssom::RGBAColorValue(0, 100, 0, 100));
  frame3.AddPropertyValue(cssom::kTopProperty,
                          new cssom::LengthValue(1.0f, cssom::kPixelsUnit));
  keyframes.push_back(frame3);

  KeyframeEffectReadOnly::Data keyframe_effect(keyframes);

  // Properties that are referenced by keyframes should be reported as being
  // animated.
  EXPECT_TRUE(keyframe_effect.IsPropertyAnimated(cssom::kColorProperty));
  EXPECT_TRUE(keyframe_effect.IsPropertyAnimated(cssom::kOpacityProperty));
  EXPECT_TRUE(
      keyframe_effect.IsPropertyAnimated(cssom::kBackgroundColorProperty));
  EXPECT_TRUE(keyframe_effect.IsPropertyAnimated(cssom::kTopProperty));

  // Properties we did not reference in keyframes should not be reported as
  // being animated.
  EXPECT_FALSE(keyframe_effect.IsPropertyAnimated(cssom::kLeftProperty));
  EXPECT_FALSE(keyframe_effect.IsPropertyAnimated(cssom::kFontSizeProperty));
  EXPECT_FALSE(keyframe_effect.IsPropertyAnimated(cssom::kTransformProperty));
}

namespace {
std::vector<Keyframe::Data> AddNoiseKeyframes(
    const std::vector<Keyframe::Data>& keyframes) {
  // Adds noise keyframes to the set of keyframes.  Noise here means other
  // keyframes with a "NULL" target property so that they are guaranteed to
  // not match any property that any of these tests wish to animate.
  // Additionally, existing keyframes will have a "NULL" target property added
  // to them.
  std::vector<Keyframe::Data> noisy_keyframes;

  // Add an initial noise keyframe at offset 0 to start the sequence.
  Keyframe::Data noise_keyframe_begin(0.0);
  noise_keyframe_begin.AddPropertyValue(cssom::kNoneProperty,
                                        new cssom::NumberValue(0));
  noisy_keyframes.push_back(noise_keyframe_begin);

  for (std::vector<Keyframe::Data>::const_iterator iter = keyframes.begin();
       iter != keyframes.end(); ++iter) {
    Keyframe::Data noise_keyframe(*iter->offset());
    noise_keyframe.AddPropertyValue(cssom::kNoneProperty,
                                    new cssom::NumberValue(0));

    // Add one noise keyframe before the real keyframe
    noisy_keyframes.push_back(noise_keyframe);

    // Add the real keyframe, with a noise property added to it.
    Keyframe::Data real_keyframe = *iter;
    real_keyframe.AddPropertyValue(cssom::kNoneProperty,
                                   new cssom::NumberValue(0));
    noisy_keyframes.push_back(real_keyframe);

    // Add one noise keyframe after the real keyframe.
    noisy_keyframes.push_back(noise_keyframe);
  }

  // Add a final noise keyframe at offset 1 to end the sequence.
  Keyframe::Data noise_keyframe_end(1.0);
  noise_keyframe_end.AddPropertyValue(cssom::kNoneProperty,
                                      new cssom::NumberValue(0));
  noisy_keyframes.push_back(noise_keyframe_end);

  return noisy_keyframes;
}

KeyframeEffectReadOnly::Data CreateKeyframeEffectWithTwoNumberKeyframes(
    cssom::PropertyKey target_property, bool add_noise_keyframes,
    double offset1, float value1, double offset2, float value2) {
  std::vector<Keyframe::Data> keyframes;

  Keyframe::Data frame1(offset1);
  frame1.AddPropertyValue(target_property, new cssom::NumberValue(value1));
  keyframes.push_back(frame1);

  Keyframe::Data frame2(offset2);
  frame2.AddPropertyValue(target_property, new cssom::NumberValue(value2));
  keyframes.push_back(frame2);

  return KeyframeEffectReadOnly::Data(
      add_noise_keyframes ? AddNoiseKeyframes(keyframes) : keyframes);
}

KeyframeEffectReadOnly::Data CreateKeyframeEffectWithThreeNumberKeyframes(
    cssom::PropertyKey target_property, bool add_noise_keyframes,
    double offset1, float value1, double offset2, float value2, double offset3,
    float value3) {
  std::vector<Keyframe::Data> keyframes;

  Keyframe::Data frame1(offset1);
  frame1.AddPropertyValue(target_property, new cssom::NumberValue(value1));
  keyframes.push_back(frame1);

  Keyframe::Data frame2(offset2);
  frame2.AddPropertyValue(target_property, new cssom::NumberValue(value2));
  keyframes.push_back(frame2);

  Keyframe::Data frame3(offset3);
  frame3.AddPropertyValue(target_property, new cssom::NumberValue(value3));
  keyframes.push_back(frame3);

  return KeyframeEffectReadOnly::Data(
      add_noise_keyframes ? AddNoiseKeyframes(keyframes) : keyframes);
}

template <typename T>
scoped_refptr<T> ComputeAnimatedPropertyValueTyped(
    const KeyframeEffectReadOnly::Data& effect,
    cssom::PropertyKey target_property,
    const scoped_refptr<cssom::PropertyValue>& underlying_value,
    double iteration_progress, double current_iteration) {
  scoped_refptr<cssom::PropertyValue> animated =
      effect.ComputeAnimatedPropertyValue(target_property, underlying_value,
                                          iteration_progress,
                                          current_iteration);
  scoped_refptr<T> animated_typed = dynamic_cast<T*>(animated.get());
  DCHECK(animated_typed);

  return animated_typed;
}
}  // namespace

// We parameterize the following suite of tests on whether or not "noise
// keyframes" are to be included in the tests.  Since all of these tests will
// be targetting a single property, "noise keyframes" means that the keyframe
// effects will contain keyframes for properties that are not our target
// property, and the keyframes that do contain our target property will also
// refer to our noise property.  Essentially, all test results need to be
// the same regardless of whether noise is present or not, as when animating
// a single property, we only care about keyframes that contain that property.
class KeyframeEffectReadOnlyDataSingleParameterKeyframeTests
    : public ::testing::TestWithParam<bool> {};

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       NoPropertySpecificKeyframes) {
  // If we create a keyframe effect that animates opacity, then applying it
  // to all other properties should simply return the underlying value for
  // the other properties.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.0, 0.25f, 1.0, 0.75f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kLeftProperty, underlying_value, 0.5, 0);

  EXPECT_TRUE(animated->Equals(*underlying_value));
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       Offset0AutoPopulatesWithUnderlyingValue) {
  // If our keyframe effect does not specify a value for offset 0, it should
  // be created automatically from the underlying value.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.5, 0.8f, 1.0, 1.0f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 0.25, 0);

  EXPECT_FLOAT_EQ(0.45f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       Offset1AutoPopulatesWithUnderlyingValue) {
  // If our keyframe effect does not specify a value for offset 0, it should
  // be created automatically from the underlying value.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.0, 0.0f, 0.5, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 0.75, 0);

  EXPECT_FLOAT_EQ(0.45f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       NegativeIterationProgressReturnsFirstOffset0Value) {
  // If iteration progress is less than 0 and we have multiple keyframes with
  // offset 0, we should return the value of the first of these.
  // Step 10 from:
  //   https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#the-effect-value-of-a-keyframe-animation-effect
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.0, 0.2f, 0.0, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, -1.0, 0);

  EXPECT_FLOAT_EQ(0.2f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       IterationProgressGreaterThan1ReturnsLastOffset1Value) {
  // If iteration progress is greater than 1 and we have multiple keyframes with
  // offset 1, we should return the value of the last of these.
  // Step 10 from:
  //   https://www.w3.org/TR/2015/WD-web-animations-1-20150707/#the-effect-value-of-a-keyframe-animation-effect
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 1.0, 0.2f, 1.0, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 2.0, 0);

  EXPECT_FLOAT_EQ(0.8f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       IterationProgressLessThan0Extrapolates) {
  // If iteration progress is greater than 1, we should extrapolate from the
  // last keyframe.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.0, 0.2f, 1.0, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, -1.0, 0);

  EXPECT_FLOAT_EQ(-0.4f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       IterationProgressLessThan0ExtrapolatesWithoutExplicit0OffsetKeyframe) {
  // If iteration progress is greater than 1, we should extrapolate from the
  // last keyframe.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.5, 0.2f, 1.0, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, -1.0, 0);

  EXPECT_FLOAT_EQ(-0.1f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       IterationProgressGreaterThan1Extrapolates) {
  // If iteration progress is greater than 1, we should extrapolate from the
  // last keyframe.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.0, 0.2f, 1.0, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 2.0, 0);

  EXPECT_FLOAT_EQ(1.4f, animated->value());
}

TEST_P(
    KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
    IterationProgressGreaterThan1ExtrapolatesWithoutExplicit1OffsetKeyframe) {
  // If iteration progress is greater than 1, we should extrapolate from the
  // last keyframe.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.0, 0.2f, 0.5, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.9f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 2.0, 0);

  EXPECT_FLOAT_EQ(1.1f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       LastKeyframeWithSameOffsetIsChosenAsFirstEndpoint) {
  // If we have two keyframes with the same offset, and that offset is chosen
  // as the offset of the first interval endpoint, then we use the last keyframe
  // with the given offset.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.5, 0.2f, 0.5, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.9f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 0.75, 0);

  EXPECT_FLOAT_EQ(0.85f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       KeyframeAfterFirstIntervalEndpointIsSecondIntervalEndpoint) {
  // Check that the very next keyframe after our first interval endpoint is
  // the one chosen as the second interval endpoint.  E.g., if we have two
  // candidates for the second endpoint with the same offset, the first of
  // those is chosen.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithTwoNumberKeyframes(
          cssom::kOpacityProperty, GetParam(), 0.5, 0.2f, 0.5, 0.8f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.1f);

  scoped_refptr<cssom::NumberValue> animated =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 0.25, 0);

  EXPECT_FLOAT_EQ(0.15f, animated->value());
}

TEST_P(KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
       AllIntervalsOfMultiIntervalEffectEvaluateCorrectly) {
  // Check that all 4 intervals in a 3-keyframe effect evaluate to the correct
  // values.
  KeyframeEffectReadOnly::Data effect =
      CreateKeyframeEffectWithThreeNumberKeyframes(cssom::kOpacityProperty,
                                                   GetParam(), 0.25, 0.1f, 0.5,
                                                   0.5f, 0.75, 0.9f);

  scoped_refptr<cssom::NumberValue> underlying_value =
      new cssom::NumberValue(0.0f);

  scoped_refptr<cssom::NumberValue> animated1 =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 0.125, 0);
  EXPECT_FLOAT_EQ(0.05f, animated1->value());

  scoped_refptr<cssom::NumberValue> animated2 =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 0.375, 0);
  EXPECT_FLOAT_EQ(0.3f, animated2->value());

  scoped_refptr<cssom::NumberValue> animated3 =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 0.625, 0);
  EXPECT_FLOAT_EQ(0.7f, animated3->value());

  scoped_refptr<cssom::NumberValue> animated4 =
      ComputeAnimatedPropertyValueTyped<cssom::NumberValue>(
          effect, cssom::kOpacityProperty, underlying_value, 0.875, 0);
  EXPECT_FLOAT_EQ(0.45f, animated4->value());
}

INSTANTIATE_TEST_CASE_P(WithAndWithoutNoise,
                        KeyframeEffectReadOnlyDataSingleParameterKeyframeTests,
                        ::testing::Bool());

}  // namespace web_animations
}  // namespace cobalt
