// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/color/color_provider_key.h"

#include <optional>

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/color/color_provider.h"
#include "ui/color/system_theme.h"

namespace ui {
namespace {

class TestInitializerSupplier : public ColorProviderKey::InitializerSupplier {
 public:
  void AddColorMixers(ColorProvider* provider,
                      const ColorProviderKey& key) const override {}
};

class TestThemeInitializerSupplier
    : public ColorProviderKey::ThemeInitializerSupplier {
 public:
  explicit TestThemeInitializerSupplier(ThemeType theme_type)
      : ThemeInitializerSupplier(theme_type) {}
  void AddColorMixers(ColorProvider* provider,
                      const ColorProviderKey& key) const override {}
  bool GetColor(int id, SkColor* color) const override { return false; }
  bool GetTint(int id, color_utils::HSL* hsl) const override { return false; }
  bool GetDisplayProperty(int id, int* result) const override { return false; }
  bool HasCustomImage(int id) const override { return false; }

 protected:
  ~TestThemeInitializerSupplier() override = default;
};

TEST(ColorProviderKeyTest, EqualityDefaultKeys) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  EXPECT_EQ(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityColorMode) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.color_mode = ColorProviderKey::ColorMode::kLight;
  key2.color_mode = ColorProviderKey::ColorMode::kDark;
  EXPECT_NE(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityContrastMode) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.contrast_mode = ColorProviderKey::ContrastMode::kNormal;
  key2.contrast_mode = ColorProviderKey::ContrastMode::kHigh;
  EXPECT_NE(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityForcedColors) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.forced_colors = ColorProviderKey::ForcedColors::kNone;
  key2.forced_colors = ColorProviderKey::ForcedColors::kSystem;
  EXPECT_NE(key1, key2);

  key2.forced_colors = ColorProviderKey::ForcedColors::kDusk;
  EXPECT_NE(key1, key2);
}

TEST(ColorProviderKeyTest, EqualitySystemTheme) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.system_theme = SystemTheme::kDefault;
  key2.system_theme =
      static_cast<SystemTheme>(static_cast<int>(SystemTheme::kDefault) + 1);
  EXPECT_NE(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityFrameType) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.frame_type = ColorProviderKey::FrameType::kChromium;
  key2.frame_type = ColorProviderKey::FrameType::kNative;
  EXPECT_NE(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityFrameStyle) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.frame_style = ColorProviderKey::FrameStyle::kDefault;
  key2.frame_style = ColorProviderKey::FrameStyle::kSystem;
  EXPECT_NE(key1, key2);

  key2.frame_style = ColorProviderKey::FrameStyle::kGlass;
  EXPECT_NE(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityUserColorSource) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.user_color_source = ColorProviderKey::UserColorSource::kAccent;
  key2.user_color_source = ColorProviderKey::UserColorSource::kBaseline;
  EXPECT_NE(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityUserColor) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.user_color = SK_ColorRED;
  key2.user_color = std::nullopt;
  EXPECT_NE(key1, key2);

  key2.user_color = SK_ColorBLUE;
  EXPECT_NE(key1, key2);

  key2.user_color = SK_ColorRED;
  EXPECT_EQ(key1, key2);
}

TEST(ColorProviderKeyTest, EqualitySchemeVariant) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.scheme_variant = ColorProviderKey::SchemeVariant::kTonalSpot;
  key2.scheme_variant = std::nullopt;
  EXPECT_NE(key1, key2);

  key2.scheme_variant = ColorProviderKey::SchemeVariant::kVibrant;
  EXPECT_NE(key1, key2);

  key2.scheme_variant = ColorProviderKey::SchemeVariant::kTonalSpot;
  EXPECT_EQ(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityCustomTheme) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  auto theme1 = base::MakeRefCounted<TestThemeInitializerSupplier>(
      ColorProviderKey::ThemeInitializerSupplier::ThemeType::kExtension);
  auto theme2 = base::MakeRefCounted<TestThemeInitializerSupplier>(
      ColorProviderKey::ThemeInitializerSupplier::ThemeType::kAutogenerated);

  key1.custom_theme = theme1;
  key2.custom_theme = nullptr;
  EXPECT_NE(key1, key2);

  key2.custom_theme = theme2;
  EXPECT_NE(key1, key2);

  key2.custom_theme = theme1;
  EXPECT_EQ(key1, key2);
}

TEST(ColorProviderKeyTest, EqualityAppController) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  TestInitializerSupplier supplier1;
  TestInitializerSupplier supplier2;

  key1.app_controller = &supplier1;
  key2.app_controller = nullptr;
  EXPECT_NE(key1, key2);

  key2.app_controller = &supplier2;
  EXPECT_NE(key1, key2);

  key2.app_controller = &supplier1;
  EXPECT_EQ(key1, key2);
}

TEST(ColorProviderKeyTest, EqualitySystemThemeVersion) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.system_theme_version = 1;
  key2.system_theme_version = 2;
  EXPECT_NE(key1, key2);

  key2.system_theme_version = 1;
  EXPECT_EQ(key1, key2);
}

#if BUILDFLAG(IS_ANDROID)
TEST(ColorProviderKeyTest, EqualityContextHash) {
  ColorProviderKey key1;
  ColorProviderKey key2;
  key1.context_hash = 12345;
  key2.context_hash = 67890;
  EXPECT_NE(key1, key2);

  key2.context_hash = 12345;
  EXPECT_EQ(key1, key2);
}
#endif

}  // namespace
}  // namespace ui
