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

#ifndef COMPONENTS_SYNC_BASE_USER_SELECTABLE_TYPE_H_
#define COMPONENTS_SYNC_BASE_USER_SELECTABLE_TYPE_H_

#include <iosfwd>
#include <optional>
#include <string>

#include "base/containers/enum_set.h"
#include "components/sync/base/data_type.h"

namespace syncer {

// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.sync
// LINT.IfChange(UserSelectableType)
enum class UserSelectableType {
  kBookmarks,
  kFirstType = kBookmarks,

  kPreferences,
  kPasswords,
  kAutofill,
  kThemes,
  kHistory,
  kExtensions,
  kApps,
  kReadingList,
  kTabs,
  kSavedTabGroups,
  kPayments,
  kProductComparison,
  kCookies,
  kLastType = kCookies
};
// LINT.ThenChange(/chrome/browser/resources/settings_shared/people_page/sync_browser_proxy.ts:UserSelectableType)

using UserSelectableTypeSet = base::EnumSet<UserSelectableType,
                                            UserSelectableType::kFirstType,
                                            UserSelectableType::kLastType>;

const char* GetUserSelectableTypeName(UserSelectableType type);
// Returns the type if the string matches a known type.
std::optional<UserSelectableType> GetUserSelectableTypeFromString(
    const std::string& type);
std::string UserSelectableTypeSetToString(UserSelectableTypeSet types);
DataTypeSet UserSelectableTypeToAllDataTypes(UserSelectableType type);

base::ListValue UserSelectableTypeSetToValueList(
    syncer::UserSelectableTypeSet user_selected_types);
syncer::UserSelectableTypeSet ValueListToUserSelectableTypeSet(
    const base::ListValue& value_list);

DataType UserSelectableTypeToCanonicalDataType(UserSelectableType type);

// Do not use this function for data types which have multiple corresponding
// user selectable types.
std::optional<UserSelectableType> GetUserSelectableTypeFromDataType(
    DataType data_type);

#if BUILDFLAG(IS_CHROMEOS)
// Chrome OS provides a separate UI with sync controls for OS data types. Note
// that wallpaper is a special case due to its reliance on apps, so while it
// appears in the UI, it is not included in this enum.
// TODO(crbug.com/40629581): Break this dependency.
enum class UserSelectableOsType {
  kOsApps,
  kFirstType = kOsApps,

  kOsPreferences,
  kOsWifiConfigurations,
  kLastType = kOsWifiConfigurations
};

using UserSelectableOsTypeSet = base::EnumSet<UserSelectableOsType,
                                              UserSelectableOsType::kFirstType,
                                              UserSelectableOsType::kLastType>;

const char* GetUserSelectableOsTypeName(UserSelectableOsType type);
std::string UserSelectableOsTypeSetToString(UserSelectableOsTypeSet types);
DataTypeSet UserSelectableOsTypeToAllDataTypes(UserSelectableOsType type);
DataType UserSelectableOsTypeToCanonicalDataType(UserSelectableOsType type);

// Returns the type if the string matches a known OS type.
std::optional<UserSelectableOsType> GetUserSelectableOsTypeFromString(
    const std::string& type);

base::ListValue UserSelectableOsTypeSetToValueList(
    syncer::UserSelectableOsTypeSet user_selected_types);
syncer::UserSelectableOsTypeSet ValueListToUserSelectableOsTypeSet(
    const base::ListValue& value_list);
#endif  // BUILDFLAG(IS_CHROMEOS)

// For GTest.
std::ostream& operator<<(std::ostream& stream, const UserSelectableType& type);
std::ostream& operator<<(std::ostream& stream,
                         const UserSelectableTypeSet& types);

}  // namespace syncer

#endif  // COMPONENTS_SYNC_BASE_USER_SELECTABLE_TYPE_H_
