// 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/css_transition_set.h"

#include <memory>
#include <utility>

#include "base/time/time.h"
#include "cobalt/cssom/css_computed_style_data.h"
#include "cobalt/cssom/css_transition.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/cssom/length_value.h"
#include "cobalt/cssom/number_value.h"
#include "cobalt/cssom/property_key_list_value.h"
#include "cobalt/cssom/property_list_value.h"
#include "cobalt/cssom/rgba_color_value.h"
#include "cobalt/cssom/string_value.h"
#include "cobalt/cssom/time_list_value.h"
#include "cobalt/cssom/timing_function.h"
#include "cobalt/cssom/timing_function_list_value.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

namespace {
scoped_refptr<TimeListValue> MakeTimeListWithSingleTime(float time_in_seconds) {
  std::unique_ptr<TimeListValue::Builder> time_list(
      new TimeListValue::Builder());
  time_list->push_back(base::TimeDelta::FromMicroseconds(static_cast<int64>(
      time_in_seconds * base::Time::kMicrosecondsPerSecond)));
  return base::WrapRefCounted(new TimeListValue(std::move(time_list)));
}

scoped_refptr<PropertyListValue> MakePropertyListWithSingleProperty(
    const scoped_refptr<PropertyValue>& property_value) {
  std::unique_ptr<PropertyListValue::Builder> property_list_builder(
      new PropertyListValue::Builder());
  property_list_builder->push_back(property_value.get());
  return base::WrapRefCounted(
      new PropertyListValue(std::move(property_list_builder)));
}

scoped_refptr<PropertyKeyListValue> MakePropertyNameListWithSingleProperty(
    PropertyKey property) {
  std::unique_ptr<PropertyKeyListValue::Builder> property_name_list(
      new PropertyKeyListValue::Builder());
  property_name_list->push_back(property);
  return base::WrapRefCounted(
      new PropertyKeyListValue(std::move(property_name_list)));
}

scoped_refptr<TimingFunctionListValue> MakeTimingFunctionWithSingleProperty(
    const scoped_refptr<TimingFunction>& timing_function) {
  std::unique_ptr<TimingFunctionListValue::Builder> timing_function_list(
      new TimingFunctionListValue::Builder());
  timing_function_list->push_back(timing_function);
  return base::WrapRefCounted(
      new TimingFunctionListValue(std::move(timing_function_list)));
}

scoped_refptr<MutableCSSComputedStyleData> CreateTestComputedData() {
  scoped_refptr<MutableCSSComputedStyleData> initial_data =
      new MutableCSSComputedStyleData();

  initial_data->set_background_color(new RGBAColorValue(0xffffffff));
  initial_data->set_color(new RGBAColorValue(0x00000000));
  initial_data->set_display(KeywordValue::GetBlock());
  initial_data->set_is_inline_before_blockification(false);
  initial_data->set_font_family(
      MakePropertyListWithSingleProperty(new StringValue("Roboto")));
  initial_data->set_font_size(new LengthValue(16, kPixelsUnit));
  initial_data->set_height(new LengthValue(400, kPixelsUnit));
  initial_data->set_opacity(new NumberValue(0.5f));
  initial_data->set_width(new LengthValue(400, kPixelsUnit));
  initial_data->set_transform(KeywordValue::GetNone());
  initial_data->set_transition_delay(MakeTimeListWithSingleTime(0.0f));
  initial_data->set_transition_duration(MakeTimeListWithSingleTime(0.0f));
  initial_data->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));
  initial_data->set_transition_timing_function(
      MakeTimingFunctionWithSingleProperty(TimingFunction::GetLinear()));

  return initial_data;
}
}  // namespace

class TransitionSetTest : public testing::Test {
 public:
  TransitionSetTest() {
    // Initialize start and end styles to the same data.
    start_ = CreateTestComputedData();
    end_ = CreateTestComputedData();
  }

 protected:
  scoped_refptr<MutableCSSComputedStyleData> start_;
  scoped_refptr<MutableCSSComputedStyleData> end_;
};

TEST_F(TransitionSetTest, TransitionSetStartsEmpty) {
  TransitionSet transition_set;
  EXPECT_TRUE(transition_set.empty());
}

TEST_F(TransitionSetTest, TransitionPropertyOfAllGeneratesATransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_FALSE(transition_set.empty());
  EXPECT_TRUE(
      transition_set.GetTransitionForProperty(kBackgroundColorProperty));
}

TEST_F(TransitionSetTest,
       TransitionPropertyOfSpecificValueGeneratesATransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kBackgroundColorProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_FALSE(transition_set.empty());
  EXPECT_TRUE(
      transition_set.GetTransitionForProperty(kBackgroundColorProperty));
}

TEST_F(TransitionSetTest, TransitionPropertyOfNoneGeneratesNoTransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(KeywordValue::GetNone());

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_TRUE(transition_set.empty());
}

TEST_F(TransitionSetTest, TransitionDurationOfZeroGeneratesNoTransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(0.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kBackgroundColorProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_TRUE(transition_set.empty());
  EXPECT_EQ(static_cast<Transition*>(NULL),
            transition_set.GetTransitionForProperty(kBackgroundColorProperty));
}

TEST_F(TransitionSetTest, NoStyleChangesGeneratesNoTransitions) {
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kBackgroundColorProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_TRUE(transition_set.empty());
}

TEST_F(TransitionSetTest, TransitionDelayIsAccountedFor) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_delay(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kBackgroundColorProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  const Transition* transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);
  EXPECT_EQ(base::TimeDelta::FromSeconds(1), transition->delay());
}

// Here we start testing that the produced transitions are actually
// transitioning a given element correctly.  We use background color since it is
// the first animatable property we have available when these tests were
// written.
namespace {
void CheckTransitionsEqual(const Transition& a, const Transition& b) {
  EXPECT_TRUE(a.start_value()->Equals(*b.start_value()));
  EXPECT_TRUE(a.end_value()->Equals(*b.end_value()));
  EXPECT_TRUE(a.reversing_adjusted_start_value()->Equals(
      *b.reversing_adjusted_start_value()));

  const float kErrorEpsilon = 0.00015f;

  EXPECT_NEAR(a.duration().InSecondsF(), b.duration().InSecondsF(),
              kErrorEpsilon);
  EXPECT_NEAR(a.delay().InSecondsF(), b.delay().InSecondsF(), kErrorEpsilon);
  EXPECT_EQ(a.start_time(), b.start_time());
  EXPECT_EQ(a.target_property(), b.target_property());
  EXPECT_NEAR(a.reversing_shortening_factor(), b.reversing_shortening_factor(),
              kErrorEpsilon);
}
}  // namespace

TEST_F(TransitionSetTest, TransitionSetProducesValidFirstTransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_FALSE(transition_set.empty());
  const Transition* transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  Transition expected_transition(
      kBackgroundColorProperty, new RGBAColorValue(0xffffffff),
      new RGBAColorValue(0x00000000), base::TimeDelta(),
      base::TimeDelta::FromSeconds(1), base::TimeDelta(),
      TimingFunction::GetLinear(), new RGBAColorValue(0xffffffff), 1.0f);

  CheckTransitionsEqual(expected_transition, *transition);

  // The transition should remain untouched if the style remains unchanged and
  // the transition has not completed.
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.5), *end_,
                                   *end_);

  EXPECT_FALSE(transition_set.empty());
  transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  CheckTransitionsEqual(expected_transition, *transition);
}

TEST_F(TransitionSetTest, TransitionSetRemovesTransitionAfterCompletion) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_FALSE(transition_set.empty());
  EXPECT_TRUE(
      transition_set.GetTransitionForProperty(kBackgroundColorProperty));

  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(2.0), *end_,
                                   *end_);

  EXPECT_TRUE(transition_set.empty());
  EXPECT_EQ(static_cast<Transition*>(NULL),
            transition_set.GetTransitionForProperty(kBackgroundColorProperty));
}

TEST_F(TransitionSetTest, TransitionsFromTransitionsWork) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));
  scoped_refptr<MutableCSSComputedStyleData> end2 = CreateTestComputedData();
  end2->set_background_color(new RGBAColorValue(0x000000ff));
  end2->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end2->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.5), *end_,
                                   *end2);

  EXPECT_FALSE(transition_set.empty());
  const Transition* transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  CheckTransitionsEqual(
      Transition(
          kBackgroundColorProperty, new RGBAColorValue(0x80808080),
          new RGBAColorValue(0x000000ff), base::TimeDelta::FromSecondsD(0.5),
          base::TimeDelta::FromSecondsD(1.0f), base::TimeDelta(),
          TimingFunction::GetLinear(), new RGBAColorValue(0x80808080), 1.0f),
      *transition);
}

TEST_F(TransitionSetTest, ReverseTransitionsWork) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));
  start_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  start_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.5), *end_,
                                   *start_);

  EXPECT_FALSE(transition_set.empty());
  const Transition* transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  CheckTransitionsEqual(
      Transition(
          kBackgroundColorProperty, new RGBAColorValue(0x80808080),
          new RGBAColorValue(0xffffffff), base::TimeDelta::FromSecondsD(0.5),
          base::TimeDelta::FromSecondsD(0.5f), base::TimeDelta(),
          TimingFunction::GetLinear(), new RGBAColorValue(0x00000000), 0.5f),
      *transition);

  // Let's try reversing the transition again.
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.75), *start_,
                                   *end_);

  EXPECT_FALSE(transition_set.empty());
  transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  CheckTransitionsEqual(
      Transition(
          kBackgroundColorProperty, new RGBAColorValue(0xc0c0c0c0),
          new RGBAColorValue(0x00000000), base::TimeDelta::FromSecondsD(0.75),
          base::TimeDelta::FromSecondsD(0.75f), base::TimeDelta(),
          TimingFunction::GetLinear(), new RGBAColorValue(0xffffffff), 0.75f),
      *transition);
}

// Make sure that we successfully remove transitions when the 'transition'
// CSS property is removed (and so we return to the default setting of
// 'all' for transition an '0' for duration).
TEST_F(TransitionSetTest, ClearingTransitionsWorks) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));
  scoped_refptr<MutableCSSComputedStyleData> end2 = CreateTestComputedData();
  end2->set_background_color(new RGBAColorValue(0x000000ff));
  end2->set_transition_duration(MakeTimeListWithSingleTime(0.0f));
  end2->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.5), *end_,
                                   *end2);

  EXPECT_TRUE(transition_set.empty());
}

}  // namespace cssom
}  // namespace cobalt
