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

#include "chrome/browser/themes/theme_service_test_utils.h"

#include "base/containers/fixed_flat_map.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/themes/theme_syncable_service.h"
#include "components/sync/protocol/entity_specifics.pb.h"
#include "components/sync/protocol/theme_types.pb.h"
#include "extensions/common/manifest_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace theme_service::test {

std::ostream& operator<<(std::ostream& os, PrintableSkColor printable_color) {
  SkColor color = printable_color.color;
  return os << base::StringPrintf("#%02x%02x%02x%02x", SkColorGetA(color),
                                  SkColorGetR(color), SkColorGetG(color),
                                  SkColorGetB(color));
}

std::string ColorIdToString(ui::ColorId id) {
#define E_CPONLY(color_id, ...) {color_id, #color_id},

  static constexpr const auto kMap =
      base::MakeFixedFlatMap<ui::ColorId, const char*>({CHROME_COLOR_IDS});

#undef E_CPONLY
  return kMap.find(id)->second;
}

scoped_refptr<extensions::Extension> MakeThemeExtension(
    const base::FilePath& extension_path,
    const std::string& id,
    const std::string& name,
    extensions::mojom::ManifestLocation location,
    const std::string& update_url) {
  base::DictValue source;
  source.Set(extensions::manifest_keys::kName, name);
  source.Set(extensions::manifest_keys::kTheme, base::DictValue());
  source.Set(extensions::manifest_keys::kUpdateURL, update_url);
  source.Set(extensions::manifest_keys::kVersion, "0.0.0.0");
  std::u16string error;
  scoped_refptr<extensions::Extension> extension =
      extensions::Extension::Create(extension_path, location, source,
                                    extensions::Extension::NO_FLAGS, id,
                                    &error);
  EXPECT_TRUE(extension.get());
  EXPECT_EQ(u"", error);
  return extension;
}

syncer::SyncDataList MakeThemeDataList(
    const sync_pb::ThemeSpecifics& theme_specifics) {
  syncer::SyncDataList list;
  sync_pb::EntitySpecifics entity_specifics;
  entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
  list.push_back(syncer::SyncData::CreateLocalData(
      ThemeSyncableService::kSyncEntityClientTag,
      ThemeSyncableService::kSyncEntityTitle, entity_specifics));
  return list;
}

syncer::SyncChangeList MakeThemeChangeList(
    const sync_pb::ThemeSpecifics& theme_specifics) {
  syncer::SyncChangeList change_list;
  sync_pb::EntitySpecifics entity_specifics;
  entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
  change_list.emplace_back(
      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
      syncer::SyncData::CreateRemoteData(
          entity_specifics, syncer::ClientTagHash::FromHashed("unused")));
  return change_list;
}

sync_pb::ThemeSpecifics EmptySpecifics() {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.set_use_system_theme_by_default(false);
  theme_specifics.set_browser_color_scheme(
      ::sync_pb::ThemeSpecifics_BrowserColorScheme_SYSTEM);
  return theme_specifics;
}

sync_pb::ThemeSpecifics CreateThemeSpecificsWithExtensionTheme(
    const std::string& id,
    const std::string& name,
    const std::string& url) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_system_theme_by_default(false);
  theme_specifics.set_browser_color_scheme(
      sync_pb::ThemeSpecifics_BrowserColorScheme_SYSTEM);
  theme_specifics.set_use_custom_theme(true);
  theme_specifics.set_custom_theme_id(id);
  theme_specifics.set_custom_theme_name(name);
  theme_specifics.set_custom_theme_update_url(url);
  return theme_specifics;
}

sync_pb::ThemeSpecifics CreateThemeSpecificsWithAutogeneratedColorTheme() {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.set_use_system_theme_by_default(false);
  theme_specifics.set_browser_color_scheme(
      sync_pb::ThemeSpecifics_BrowserColorScheme_SYSTEM);
  theme_specifics.mutable_autogenerated_color_theme()->set_color(SK_ColorRED);
  return theme_specifics;
}

sync_pb::ThemeSpecifics CreateThemeSpecificsWithColorTheme() {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.set_use_system_theme_by_default(false);
  theme_specifics.set_browser_color_scheme(
      sync_pb::ThemeSpecifics_BrowserColorScheme_SYSTEM);
  sync_pb::UserColorTheme* user_color_theme =
      theme_specifics.mutable_user_color_theme();
  user_color_theme->set_color(SK_ColorRED);
  user_color_theme->set_browser_color_variant(
      sync_pb::UserColorTheme_BrowserColorVariant_TONAL_SPOT);
  return theme_specifics;
}

sync_pb::ThemeSpecifics CreateThemeSpecificsWithGrayscaleTheme() {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.set_use_system_theme_by_default(false);
  theme_specifics.set_browser_color_scheme(
      sync_pb::ThemeSpecifics_BrowserColorScheme_SYSTEM);
  theme_specifics.mutable_grayscale_theme_enabled();
  return theme_specifics;
}

sync_pb::ThemeSpecifics CreateThemeSpecificsWithCustomNtpBackground(
    const std::string& background_url) {
  sync_pb::ThemeSpecifics theme_specifics;
  theme_specifics.set_use_custom_theme(false);
  theme_specifics.set_use_system_theme_by_default(false);
  theme_specifics.set_browser_color_scheme(
      sync_pb::ThemeSpecifics_BrowserColorScheme_SYSTEM);
  sync_pb::NtpCustomBackground* background =
      theme_specifics.mutable_ntp_background();
  background->set_url(background_url);
  background->set_attribution_line_1("");
  background->set_attribution_line_2("");
  background->set_attribution_action_url("");
  background->set_collection_id("");
  background->set_resume_token("");
  background->set_refresh_timestamp_unix_epoch_seconds(0);
  return theme_specifics;
}

}  // namespace theme_service::test
