// Copyright 2013 The Flutter 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 "flutter/display_list/display_list_builder.h"
#include "flutter/display_list/display_list_comparable.h"
#include "flutter/display_list/testing/dl_test_equality.h"
#include "flutter/display_list/types.h"
#include "gtest/gtest.h"
#include "include/core/SkPath.h"
#include "include/core/SkScalar.h"

namespace flutter {
namespace testing {

TEST(DisplayListPathEffect, BuilderSetGet) {
  const SkScalar test_dashes[] = {4.0, 2.0};
  auto dash_path_effect = DlDashPathEffect::Make(test_dashes, 2, 0.0);
  DisplayListBuilder builder;
  ASSERT_EQ(builder.getPathEffect(), nullptr);
  builder.setPathEffect(dash_path_effect.get());
  ASSERT_NE(builder.getPathEffect(), nullptr);
  ASSERT_TRUE(Equals(builder.getPathEffect(),
                     static_cast<DlPathEffect*>(dash_path_effect.get())));
  builder.setPathEffect(nullptr);
  ASSERT_EQ(builder.getPathEffect(), nullptr);
}

TEST(DisplayListPathEffect, FromSkiaNullPathEffect) {
  std::shared_ptr<DlPathEffect> path_effect = DlPathEffect::From(nullptr);
  ASSERT_EQ(path_effect, nullptr);
  ASSERT_EQ(path_effect.get(), nullptr);
}

TEST(DisplayListPathEffect, FromSkiaPathEffect) {
  const SkScalar TestDashes2[] = {1.0, 1.5};
  sk_sp<SkPathEffect> sk_path_effect =
      SkDashPathEffect::Make(TestDashes2, 2, 0.0);
  std::shared_ptr<DlPathEffect> dl_path_effect =
      DlPathEffect::From(sk_path_effect);

  ASSERT_EQ(dl_path_effect->type(), DlPathEffectType::kDash);
  ASSERT_TRUE(
      Equals(dl_path_effect, DlDashPathEffect::Make(TestDashes2, 2, 0.0)));
}

TEST(DisplayListPathEffect, EffectShared) {
  const SkScalar TestDashes2[] = {1.0, 1.5};
  auto effect = DlDashPathEffect::Make(TestDashes2, 2, 0.0);
  ASSERT_TRUE(Equals(effect->shared(), effect));
}

TEST(DisplayListPathEffect, DashEffectAsDash) {
  const SkScalar TestDashes2[] = {1.0, 1.5};
  auto effect = DlDashPathEffect::Make(TestDashes2, 2, 0.0);
  ASSERT_NE(effect->asDash(), nullptr);
  ASSERT_EQ(effect->asDash(), effect.get());
}

TEST(DisplayListPathEffect, DashEffectEquals) {
  const SkScalar TestDashes2[] = {1.0, 1.5};
  auto effect1 = DlDashPathEffect::Make(TestDashes2, 2, 0.0);
  auto effect2 = DlDashPathEffect::Make(TestDashes2, 2, 0.0);
  TestEquals(*effect1, *effect1);
}

TEST(DisplayListPathEffect, CheckEffectProperties) {
  const SkScalar test_dashes[] = {4.0, 2.0};
  const SkScalar TestDashes2[] = {5.0, 2.0};
  const SkScalar TestDashes3[] = {4.0, 3.0};
  const SkScalar TestDashes4[] = {4.0, 2.0, 6.0};
  auto effect1 = DlDashPathEffect::Make(test_dashes, 2, 0.0);
  auto effect2 = DlDashPathEffect::Make(TestDashes2, 2, 0.0);
  auto effect3 = DlDashPathEffect::Make(TestDashes3, 2, 0.0);
  auto effect4 = DlDashPathEffect::Make(TestDashes4, 3, 0.0);
  auto effect5 = DlDashPathEffect::Make(test_dashes, 2, 1.0);

  TestNotEquals(*effect1, *effect2, "Interval 1 differs");
  TestNotEquals(*effect1, *effect3, "Interval 2 differs");
  TestNotEquals(*effect1, *effect4, "Dash count differs");
  TestNotEquals(*effect1, *effect5, "Dash phase differs");
}

TEST(DisplayListPathEffect, UnknownConstructor) {
  const SkScalar test_dashes[] = {4.0, 2.0};
  DlUnknownPathEffect path_effect(SkDashPathEffect::Make(test_dashes, 2, 0.0));
}

TEST(DisplayListPathEffect, UnknownShared) {
  const SkScalar test_dashes[] = {4.0, 2.0};
  DlUnknownPathEffect path_effect(SkDashPathEffect::Make(test_dashes, 2, 0.0));
  ASSERT_NE(path_effect.shared().get(), &path_effect);
  ASSERT_EQ(*path_effect.shared(), path_effect);
}

TEST(DisplayListPathEffect, UnknownContents) {
  const SkScalar test_dashes[] = {4.0, 2.0};
  sk_sp<SkPathEffect> sk_effect = SkDashPathEffect::Make(test_dashes, 2, 0.0);
  DlUnknownPathEffect effect(sk_effect);
  ASSERT_EQ(effect.skia_object(), sk_effect);
  ASSERT_EQ(effect.skia_object().get(), sk_effect.get());
}

TEST(DisplayListPathEffect, UnknownEquals) {
  const SkScalar test_dashes[] = {4.0, 2.0};
  sk_sp<SkPathEffect> sk_effect = SkDashPathEffect::Make(test_dashes, 2, 0.0);
  DlUnknownPathEffect effect1(sk_effect);
  DlUnknownPathEffect effect2(sk_effect);
  TestEquals(effect1, effect1);
}

TEST(DisplayListPathEffect, UnknownNotEquals) {
  const SkScalar test_dashes[] = {4.0, 2.0};
  // Even though the effect is the same, it is a different instance
  // and we cannot currently tell them apart because the Skia
  // DashEffect::Make objects do not implement ==
  DlUnknownPathEffect path_effect1(SkDashPathEffect::Make(test_dashes, 2, 0.0));
  DlUnknownPathEffect path_effect2(SkDashPathEffect::Make(test_dashes, 2, 0.0));
  TestNotEquals(path_effect1, path_effect2,
                "SkDashPathEffect instance differs");
}

}  // namespace testing
}  // namespace flutter
