/*
 * Copyright 2015 Google Inc. 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) {
  UNREFERENCED_PARAMETER(add_noise_keyframes);
  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) {
  UNREFERENCED_PARAMETER(add_noise_keyframes);
  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
