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

#include "components/browser_sync/common_controller_builder.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "components/autofill/core/browser/payments/autofill_wallet_data_type_controller.h"
#include "components/autofill/core/browser/webdata/addresses/autofill_profile_sync_bridge.h"
#include "components/autofill/core/browser/webdata/addresses/contact_info_data_type_controller.h"
#include "components/autofill/core/browser/webdata/addresses/contact_info_local_data_batch_uploader.h"
#include "components/autofill/core/browser/webdata/addresses/contact_info_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autocomplete/autocomplete_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_credential_sync_bridge.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_metadata_sync_bridge.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_offer_sync_bridge.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_sync_bridge.h"
#include "components/autofill/core/browser/webdata/payments/autofill_wallet_usage_data_sync_bridge.h"
#include "components/autofill/core/browser/webdata/valuables/valuable_data_type_controller.h"
#include "components/autofill/core/browser/webdata/valuables/valuable_sync_bridge.h"
#include "components/collaboration/public/collaboration_service.h"
#include "components/collaboration/public/data_type_controller/collaboration_group_data_type_controller.h"
#include "components/collaboration/public/data_type_controller/shared_tab_group_account_data_type_controller.h"
#include "components/collaboration/public/data_type_controller/shared_tab_group_data_type_controller.h"
#include "components/commerce/core/commerce_feature_list.h"
#include "components/commerce/core/product_specifications/product_specifications_service.h"
#include "components/consent_auditor/consent_auditor.h"
#include "components/data_sharing/public/data_sharing_service.h"
#include "components/data_sharing/public/features.h"
#include "components/data_sharing/public/personal_collaboration_data/personal_collaboration_data_service.h"
#include "components/history/core/browser/sync/history_data_type_controller.h"
#include "components/history/core/browser/sync/history_delete_directives_data_type_controller.h"
#include "components/password_manager/core/browser/password_store/password_store_interface.h"
#include "components/password_manager/core/browser/sharing/incoming_password_sharing_invitation_data_type_controller.h"
#include "components/password_manager/core/browser/sharing/outgoing_password_sharing_invitation_data_type_controller.h"
#include "components/password_manager/core/browser/sharing/password_receiver_service.h"
#include "components/password_manager/core/browser/sharing/password_sender_service.h"
#include "components/password_manager/core/browser/sync/password_data_type_controller.h"
#include "components/password_manager/core/browser/sync/password_local_data_batch_uploader.h"
#include "components/plus_addresses/core/browser/settings/plus_address_setting_service.h"
#include "components/plus_addresses/core/browser/sync_utils/plus_address_data_type_controller.h"
#include "components/plus_addresses/webdata/plus_address_webdata_service.h"
#include "components/prefs/pref_service.h"
#include "components/reading_list/core/dual_reading_list_model.h"
#include "components/reading_list/core/reading_list_local_data_batch_uploader.h"
#include "components/saved_tab_groups/public/tab_group_sync_service.h"
#include "components/search_engines/template_url_service.h"
#include "components/send_tab_to_self/send_tab_to_self_data_type_controller.h"
#include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
#include "components/sharing_message/sharing_message_bridge.h"
#include "components/sharing_message/sharing_message_data_type_controller.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/sync/base/data_type.h"
#include "components/sync/base/features.h"
#include "components/sync/base/report_unrecoverable_error.h"
#include "components/sync/model/forwarding_data_type_controller_delegate.h"
#include "components/sync/model/proxy_data_type_controller_delegate.h"
#include "components/sync/service/data_type_controller.h"
#include "components/sync_bookmarks/bookmark_data_type_controller.h"
#include "components/sync_bookmarks/bookmark_local_data_batch_uploader.h"
#include "components/sync_bookmarks/bookmark_sync_service.h"
#include "components/sync_device_info/device_info_sync_service.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/sync_sessions/session_data_type_controller.h"
#include "components/sync_sessions/session_sync_service.h"
#include "components/sync_user_events/user_event_data_type_controller.h"
#include "components/sync_user_events/user_event_service.h"
#include "components/variations/service/google_groups_manager.h"

#if !BUILDFLAG(IS_ANDROID)
#include "components/webauthn/core/browser/passkey_data_type_controller.h"
#include "components/webauthn/core/browser/passkey_model.h"
#endif  // !BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
#include "components/supervised_user/core/browser/supervised_user_settings_data_type_controller.h"
#include "components/supervised_user/core/browser/supervised_user_settings_service.h"
#endif  // BUILDFLAG(ENABLE_SUPERVISED_USER)

namespace browser_sync {

namespace {

using syncer::DataTypeController;
using syncer::SyncableServiceBasedDataTypeController;

// These helper functions only wrap the factory functions of the bridges. This
// way, it simplifies life for the compiler which cannot directly cast
// "WeakPtr<DataTypeSyncBridge> (AutofillWebDataService*)" to
// "WeakPtr<DataTypeControllerDelegate> (AutofillWebDataService*)".
base::WeakPtr<syncer::DataTypeControllerDelegate>
AutocompleteDelegateFromDataService(autofill::AutofillWebDataService* service) {
  return autofill::AutocompleteSyncBridge::FromWebDataService(service)
      ->change_processor()
      ->GetControllerDelegate();
}

#if !BUILDFLAG(IS_IOS)
base::WeakPtr<syncer::DataTypeControllerDelegate>
AutofillLoyaltyCardDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::ValuableSyncBridge::FromWebDataService(service)
      ->change_processor()
      ->GetControllerDelegate();
}
#endif

base::WeakPtr<syncer::DataTypeControllerDelegate>
AutofillProfileDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::AutofillProfileSyncBridge::FromWebDataService(service)
      ->change_processor()
      ->GetControllerDelegate();
}

base::WeakPtr<syncer::DataTypeControllerDelegate>
AutofillWalletCredentialDataDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::AutofillWalletCredentialSyncBridge::FromWebDataService(
             service)
      ->change_processor()
      ->GetControllerDelegate();
}

base::WeakPtr<syncer::DataTypeControllerDelegate>
AutofillWalletDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::AutofillWalletSyncBridge::FromWebDataService(service)
      ->change_processor()
      ->GetControllerDelegate();
}

base::WeakPtr<syncer::DataTypeControllerDelegate>
AutofillWalletMetadataDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::AutofillWalletMetadataSyncBridge::FromWebDataService(service)
      ->change_processor()
      ->GetControllerDelegate();
}

base::WeakPtr<syncer::DataTypeControllerDelegate>
AutofillWalletOfferDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::AutofillWalletOfferSyncBridge::FromWebDataService(service)
      ->change_processor()
      ->GetControllerDelegate();
}

#if !BUILDFLAG(IS_IOS)
base::WeakPtr<syncer::DataTypeControllerDelegate>
AutofillWalletUsageDataDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::AutofillWalletUsageDataSyncBridge::FromWebDataService(
             service)
      ->change_processor()
      ->GetControllerDelegate();
}
#endif

base::WeakPtr<syncer::DataTypeControllerDelegate>
ContactInfoDelegateFromDataService(autofill::AutofillWebDataService* service) {
  return autofill::ContactInfoSyncBridge::FromWebDataService(service)
      ->change_processor()
      ->GetControllerDelegate();
}

// Helper function that deals will null (e.g. tests, iOS webview).
base::WeakPtr<syncer::SyncableService> SyncableServiceForPrefs(
    sync_preferences::PrefServiceSyncable* prefs_service,
    syncer::DataType type) {
  return prefs_service ? prefs_service->GetSyncableService(type)->AsWeakPtr()
                       : nullptr;
}

bool ArePreferencesAllowedInTransportMode() {
  if (!base::FeatureList::IsEnabled(
          switches::kEnablePreferencesAccountStorage)) {
    return false;
  }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
  return base::FeatureList::IsEnabled(
      syncer::kReplaceSyncPromosWithSignInPromos);
#else
  return true;
#endif
}

}  // namespace

CommonControllerBuilder::CommonControllerBuilder() = default;

CommonControllerBuilder::~CommonControllerBuilder() = default;

void CommonControllerBuilder::SetAddressDataManagerGetter(
    base::RepeatingCallback<autofill::AddressDataManager*()>
        address_data_manager_getter) {
  address_data_manager_getter_ = std::move(address_data_manager_getter);
}

void CommonControllerBuilder::SetAutofillWebDataService(
    const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
    const scoped_refptr<autofill::AutofillWebDataService>&
        web_data_service_on_disk,
    const scoped_refptr<autofill::AutofillWebDataService>&
        web_data_service_in_memory) {
  autofill_web_data_ui_thread_.Set(ui_thread);
  profile_autofill_web_data_service_.Set(web_data_service_on_disk);
  account_autofill_web_data_service_.Set(web_data_service_in_memory);
}

void CommonControllerBuilder::SetBookmarkModel(
    bookmarks::BookmarkModel* bookmark_model) {
  bookmark_model_.Set(bookmark_model);
}

void CommonControllerBuilder::SetBookmarkSyncService(
    sync_bookmarks::BookmarkSyncService*
        local_or_syncable_bookmark_sync_service,
    sync_bookmarks::BookmarkSyncService* account_bookmark_sync_service) {
  local_or_syncable_bookmark_sync_service_.Set(
      local_or_syncable_bookmark_sync_service);
  account_bookmark_sync_service_.Set(account_bookmark_sync_service);
}

void CommonControllerBuilder::SetConsentAuditor(
    consent_auditor::ConsentAuditor* consent_auditor) {
  consent_auditor_.Set(consent_auditor);
}

void CommonControllerBuilder::SetCollaborationService(
    collaboration::CollaborationService* collaboration_service) {
  collaboration_service_.Set(collaboration_service);
}

void CommonControllerBuilder::SetPersonalCollaborationDataService(
    data_sharing::personal_collaboration_data::PersonalCollaborationDataService*
        personal_collaboration_data_service) {
  personal_collaboration_data_service_.Set(personal_collaboration_data_service);
}

void CommonControllerBuilder::SetDataSharingService(
    data_sharing::DataSharingService* data_sharing_service) {
  data_sharing_service_.Set(data_sharing_service);
}

void CommonControllerBuilder::SetDeviceInfoSyncService(
    syncer::DeviceInfoSyncService* device_info_sync_service) {
  device_info_sync_service_.Set(device_info_sync_service);
}

void CommonControllerBuilder::SetFaviconService(
    favicon::FaviconService* favicon_service) {
  favicon_service_.Set(favicon_service);
}

void CommonControllerBuilder::SetGoogleGroupsManager(
    GoogleGroupsManager* google_groups_manager) {
  google_groups_manager_.Set(google_groups_manager);
}

void CommonControllerBuilder::SetHistoryService(
    history::HistoryService* history_service) {
  history_service_.Set(history_service);
}

void CommonControllerBuilder::SetIdentityManager(
    signin::IdentityManager* identity_manager) {
  identity_manager_.Set(identity_manager);
}

void CommonControllerBuilder::SetDataTypeStoreService(
    syncer::DataTypeStoreService* data_type_store_service) {
  data_type_store_service_.Set(data_type_store_service);
}

#if !BUILDFLAG(IS_ANDROID)
void CommonControllerBuilder::SetPasskeyModel(
    webauthn::PasskeyModel* passkey_model) {
  passkey_model_.Set(passkey_model);
}
#endif  // !BUILDFLAG(IS_ANDROID)

void CommonControllerBuilder::SetPasswordReceiverService(
    password_manager::PasswordReceiverService* password_receiver_service) {
  password_receiver_service_.Set(password_receiver_service);
}

void CommonControllerBuilder::SetPasswordSenderService(
    password_manager::PasswordSenderService* password_sender_service) {
  password_sender_service_.Set(password_sender_service);
}

void CommonControllerBuilder::SetPasswordStore(
    const scoped_refptr<password_manager::PasswordStoreInterface>&
        profile_password_store,
    const scoped_refptr<password_manager::PasswordStoreInterface>&
        account_password_store) {
  profile_password_store_.Set(profile_password_store);
  account_password_store_.Set(account_password_store);
}

void CommonControllerBuilder::SetPlusAddressServices(
    plus_addresses::PlusAddressSettingService* plus_address_setting_service,
    const scoped_refptr<plus_addresses::PlusAddressWebDataService>&
        plus_address_webdata_service) {
  plus_address_setting_service_.Set(plus_address_setting_service);
  plus_address_webdata_service_.Set(plus_address_webdata_service);
}

void CommonControllerBuilder::SetPrefService(PrefService* pref_service) {
  pref_service_.Set(pref_service);
}

void CommonControllerBuilder::SetPrefServiceSyncable(
    sync_preferences::PrefServiceSyncable* pref_service_syncable) {
  pref_service_syncable_.Set(pref_service_syncable);
}

void CommonControllerBuilder::SetProductSpecificationsService(
    commerce::ProductSpecificationsService* product_specifications_service) {
  product_specifications_service_.Set(product_specifications_service);
}

void CommonControllerBuilder::SetDualReadingListModel(
    reading_list::DualReadingListModel* dual_reading_list_model) {
  dual_reading_list_model_.Set(dual_reading_list_model);
}

void CommonControllerBuilder::SetSendTabToSelfSyncService(
    send_tab_to_self::SendTabToSelfSyncService* send_tab_to_self_sync_service) {
  send_tab_to_self_sync_service_.Set(send_tab_to_self_sync_service);
}

void CommonControllerBuilder::SetSessionSyncService(
    sync_sessions::SessionSyncService* session_sync_service) {
  session_sync_service_.Set(session_sync_service);
}

void CommonControllerBuilder::SetSharingMessageBridge(
    SharingMessageBridge* sharing_message_bridge) {
  sharing_message_bridge_.Set(sharing_message_bridge);
}

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
void CommonControllerBuilder::SetSupervisedUserSettingsService(
    supervised_user::SupervisedUserSettingsService*
        supervised_user_settings_service) {
  supervised_user_settings_service_.Set(supervised_user_settings_service);
}
#endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)

void CommonControllerBuilder::SetTabGroupSyncService(
    tab_groups::TabGroupSyncService* tab_group_sync_service) {
  tab_group_sync_service_.Set(tab_group_sync_service);
}

void CommonControllerBuilder::SetTemplateURLService(
    TemplateURLService* template_url_service) {
  template_url_service_.Set(template_url_service);
}

void CommonControllerBuilder::SetUserEventService(
    syncer::UserEventService* user_event_service) {
  user_event_service_.Set(user_event_service);
}

std::vector<std::unique_ptr<syncer::DataTypeController>>
CommonControllerBuilder::Build(syncer::DataTypeSet disabled_types,
                               syncer::SyncService* sync_service,
                               version_info::Channel channel) {
  std::vector<std::unique_ptr<syncer::DataTypeController>> controllers;

  const base::RepeatingClosure dump_stack =
      base::BindRepeating(&syncer::ReportUnrecoverableError, channel);

  // Same delegate for full-sync or transport mode.
  controllers.push_back(std::make_unique<DataTypeController>(
      syncer::DEVICE_INFO,
      /*delegate_for_full_sync_mode=*/
      std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
          device_info_sync_service_.value()->GetControllerDelegate().get()),
      /*delegate_for_transport_mode=*/
      std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
          device_info_sync_service_.value()->GetControllerDelegate().get())));

  // These features are enabled only if there's a web data service on disk.
  if (profile_autofill_web_data_service_.value()) {
    if (!disabled_types.Has(syncer::AUTOFILL)) {
      // Note: Transport mode is not and will not be supported.
      controllers.push_back(std::make_unique<DataTypeController>(
          syncer::AUTOFILL,
          std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
              profile_autofill_web_data_service_.value()->GetDBTaskRunner(),
              base::BindRepeating(
                  &AutocompleteDelegateFromDataService,
                  base::RetainedRef(
                      profile_autofill_web_data_service_.value()))),
          /*delegate_for_transport_mode=*/nullptr));
    }

    if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
      // Note: Transport mode is not and will not be supported - support is
      // coming via CONTACT_INFO instead.
      controllers.push_back(std::make_unique<syncer::DataTypeController>(
          syncer::AUTOFILL_PROFILE,
          std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
              profile_autofill_web_data_service_.value()->GetDBTaskRunner(),
              base::BindRepeating(
                  &AutofillProfileDelegateFromDataService,
                  base::RetainedRef(
                      profile_autofill_web_data_service_.value()))),
          /*delegate_for_transport_mode=*/nullptr));
    }

    if (!disabled_types.Has(syncer::CONTACT_INFO)) {
      // The same delegate is used for full sync and transport mode.
      controllers.push_back(
          std::make_unique<autofill::ContactInfoDataTypeController>(
              /*delegate_for_full_sync_mode=*/
              std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                  profile_autofill_web_data_service_.value()->GetDBTaskRunner(),
                  base::BindRepeating(
                      &ContactInfoDelegateFromDataService,
                      base::RetainedRef(
                          profile_autofill_web_data_service_.value()))),
              /*delegate_for_transport_mode=*/
              std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                  profile_autofill_web_data_service_.value()->GetDBTaskRunner(),
                  base::BindRepeating(
                      &ContactInfoDelegateFromDataService,
                      base::RetainedRef(
                          profile_autofill_web_data_service_.value()))),
              sync_service, identity_manager_.value(),
              std::make_unique<autofill::ContactInfoLocalDataBatchUploader>(
                  std::move(address_data_manager_getter_))));
    }

    if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA)) {
      controllers.push_back(CreateWalletDataTypeController(
          syncer::AUTOFILL_WALLET_DATA,
          base::BindRepeating(&AutofillWalletDelegateFromDataService),
          sync_service, /*with_transport_mode_support=*/true));
    }

    // Wallet metadata sync depends on Wallet data sync.
    if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
        !disabled_types.Has(syncer::AUTOFILL_WALLET_METADATA)) {
      controllers.push_back(CreateWalletDataTypeController(
          syncer::AUTOFILL_WALLET_METADATA,
          base::BindRepeating(&AutofillWalletMetadataDelegateFromDataService),
          sync_service, /*with_transport_mode_support=*/
          base::FeatureList::IsEnabled(
              syncer::kReplaceSyncPromosWithSignInPromos)));
    }

    // Wallet offer sync depends on Wallet data sync.
    if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
        !disabled_types.Has(syncer::AUTOFILL_WALLET_OFFER)) {
      controllers.push_back(CreateWalletDataTypeController(
          syncer::AUTOFILL_WALLET_OFFER,
          base::BindRepeating(&AutofillWalletOfferDelegateFromDataService),
          sync_service, /*with_transport_mode_support=*/
          base::FeatureList::IsEnabled(
              syncer::kReplaceSyncPromosWithSignInPromos)));
    }

    // Wallet usage data sync depends on Wallet data sync.
#if !BUILDFLAG(IS_IOS)
    if (!disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
        !disabled_types.Has(syncer::AUTOFILL_WALLET_USAGE)) {
      controllers.push_back(CreateWalletDataTypeController(
          syncer::AUTOFILL_WALLET_USAGE,
          base::BindRepeating(&AutofillWalletUsageDataDelegateFromDataService),
          sync_service, /*with_transport_mode_support=*/true));
    }
#endif

    // Wallet credential data sync depends on Wallet data sync.
    if (base::FeatureList::IsEnabled(
            syncer::kSyncAutofillWalletCredentialData) &&
        !disabled_types.Has(syncer::AUTOFILL_WALLET_DATA) &&
        !disabled_types.Has(syncer::AUTOFILL_WALLET_CREDENTIAL)) {
      controllers.push_back(CreateWalletDataTypeController(
          syncer::AUTOFILL_WALLET_CREDENTIAL,
          base::BindRepeating(
              &AutofillWalletCredentialDataDelegateFromDataService),
          sync_service, /*with_transport_mode_support=*/true));
    }
  }

  if (!disabled_types.Has(syncer::BOOKMARKS)) {
    // Services can be null in tests.
    if (local_or_syncable_bookmark_sync_service_.value() &&
        favicon_service_.value()) {
      auto full_mode_delegate =
          std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
              local_or_syncable_bookmark_sync_service_.value()
                  ->GetBookmarkSyncControllerDelegate(favicon_service_.value())
                  .get());
      auto transport_mode_delegate =
          account_bookmark_sync_service_.value()
              ? std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                    account_bookmark_sync_service_.value()
                        ->GetBookmarkSyncControllerDelegate(
                            favicon_service_.value())
                        .get())
              : nullptr;
      controllers.push_back(
          std::make_unique<sync_bookmarks::BookmarkDataTypeController>(
              std::move(full_mode_delegate), std::move(transport_mode_delegate),
              std::make_unique<sync_bookmarks::BookmarkLocalDataBatchUploader>(
                  bookmark_model_.value(), pref_service_.value())));
    }
  }

  if (!disabled_types.Has(syncer::HISTORY)) {
    controllers.push_back(std::make_unique<history::HistoryDataTypeController>(
        sync_service, identity_manager_.value(), history_service_.value(),
        pref_service_.value()));
  }

  if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
    controllers.push_back(
        std::make_unique<history::HistoryDeleteDirectivesDataTypeController>(
            dump_stack, sync_service, data_type_store_service_.value(),
            history_service_.value(), pref_service_.value()));
  }

  if (!disabled_types.Has(syncer::SESSIONS)) {
    syncer::DataTypeControllerDelegate* delegate =
        session_sync_service_.value()->GetControllerDelegate().get();
    auto full_sync_mode_delegate =
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            delegate);
    auto transport_mode_delegate =
        base::FeatureList::IsEnabled(syncer::kReplaceSyncPromosWithSignInPromos)
            ? std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                  delegate)
            : nullptr;
    controllers.push_back(
        std::make_unique<sync_sessions::SessionDataTypeController>(
            sync_service, pref_service_.value(),
            std::move(full_sync_mode_delegate),
            std::move(transport_mode_delegate)));
  }

  if (!disabled_types.Has(syncer::PASSWORDS)) {
    if (profile_password_store_.value()) {
      // |profile_password_store_| can be null in tests.
      controllers.push_back(std::make_unique<
                            password_manager::PasswordDataTypeController>(
          profile_password_store_.value()->CreateSyncControllerDelegate(),
          account_password_store_.value()
              ? account_password_store_.value()->CreateSyncControllerDelegate()
              : nullptr,
          std::make_unique<password_manager::PasswordLocalDataBatchUploader>(
              profile_password_store_.value(),
              account_password_store_.value())));

      // Couple password sharing invitations with password data type.
      if (!disabled_types.Has(syncer::INCOMING_PASSWORD_SHARING_INVITATION) &&
          password_receiver_service_.value()) {
        controllers.push_back(
            std::make_unique<
                password_manager::
                    IncomingPasswordSharingInvitationDataTypeController>(
                sync_service, password_receiver_service_.value(),
                pref_service_.value()));
      }

      if (!disabled_types.Has(syncer::OUTGOING_PASSWORD_SHARING_INVITATION) &&
          password_sender_service_.value()) {
        controllers.push_back(
            std::make_unique<
                password_manager::
                    OutgoingPasswordSharingInvitationDataTypeController>(
                sync_service, password_sender_service_.value(),
                pref_service_.value()));
      }
    }
  }

  // `plus_address_webdata_service_` is null on iOS WebView.
  // `kEnterprisePlusAddressServerUrl` is checked to prevent enabling the
  // feature in dev builds via the field trial config.
  if (!disabled_types.Has(syncer::PLUS_ADDRESS) &&
      plus_address_webdata_service_.value() && google_groups_manager_.value()) {
    controllers.push_back(
        std::make_unique<plus_addresses::PlusAddressDataTypeController>(
            syncer::PLUS_ADDRESS,
            /*delegate_for_full_sync_mode=*/
            plus_address_webdata_service_.value()->GetSyncControllerDelegate(),
            /*delegate_for_transport_mode=*/
            plus_address_webdata_service_.value()->GetSyncControllerDelegate(),
            sync_service, identity_manager_.value(),
            google_groups_manager_.value()));
  }

  // `plus_address_setting_service_` is null on iOS WebView.
  // `kEnterprisePlusAddressServerUrl` is checked to prevent enabling the
  // feature in dev builds via the field trial config.
  if (!disabled_types.Has(syncer::PLUS_ADDRESS_SETTING) &&
      plus_address_setting_service_.value() && google_groups_manager_.value()) {
    controllers.push_back(
        std::make_unique<plus_addresses::PlusAddressDataTypeController>(
            syncer::PLUS_ADDRESS_SETTING,
            /*delegate_for_full_sync_mode=*/
            plus_address_setting_service_.value()->GetSyncControllerDelegate(),
            /*delegate_for_transport_mode=*/
            plus_address_setting_service_.value()->GetSyncControllerDelegate(),
            sync_service, identity_manager_.value(),
            google_groups_manager_.value()));
  }

  if (!disabled_types.Has(syncer::PREFERENCES)) {
    controllers.push_back(
        std::make_unique<SyncableServiceBasedDataTypeController>(
            syncer::PREFERENCES,
            data_type_store_service_.value()->GetStoreFactory(),
            SyncableServiceForPrefs(pref_service_syncable_.value(),
                                    syncer::PREFERENCES),
            dump_stack,
            ArePreferencesAllowedInTransportMode()
                ? SyncableServiceBasedDataTypeController::DelegateMode::
                      kTransportModeWithSingleModel
                : SyncableServiceBasedDataTypeController::DelegateMode::
                      kLegacyFullSyncModeOnly));
  }

  if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) {
    controllers.push_back(
        std::make_unique<SyncableServiceBasedDataTypeController>(
            syncer::PRIORITY_PREFERENCES,
            data_type_store_service_.value()->GetStoreFactory(),
            SyncableServiceForPrefs(pref_service_syncable_.value(),
                                    syncer::PRIORITY_PREFERENCES),
            dump_stack,
            ArePreferencesAllowedInTransportMode()
                ? SyncableServiceBasedDataTypeController::DelegateMode::
                      kTransportModeWithSingleModel
                : SyncableServiceBasedDataTypeController::DelegateMode::
                      kLegacyFullSyncModeOnly));
  }

  if (!disabled_types.Has(syncer::SAVED_TAB_GROUP) &&
      tab_group_sync_service_.value()) {
    syncer::DataTypeControllerDelegate* delegate =
        tab_group_sync_service_.value()
            ->GetSavedTabGroupControllerDelegate()
            .get();

    controllers.push_back(std::make_unique<syncer::DataTypeController>(
        syncer::SAVED_TAB_GROUP,
        /*delegate_for_full_sync_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            delegate),
        /*delegate_for_transport_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            delegate)));
  }

  bool data_sharing_enabled =
      data_sharing::features::IsDataSharingFunctionalityEnabled();
  if (!disabled_types.Has(syncer::SHARED_TAB_GROUP_DATA) &&
      tab_group_sync_service_.value() && data_sharing_enabled) {
    syncer::DataTypeControllerDelegate* delegate =
        tab_group_sync_service_.value()
            ->GetSharedTabGroupControllerDelegate()
            .get();

    controllers.push_back(
        std::make_unique<collaboration::SharedTabGroupDataTypeController>(
            /*delegate_for_full_sync_mode=*/
            std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                delegate),
            /*delegate_for_transport_mode=*/
            std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                delegate),
            sync_service, collaboration_service_.value()));
  }

  if (!disabled_types.Has(syncer::SHARING_MESSAGE) &&
      sharing_message_bridge_.value()) {
    syncer::DataTypeControllerDelegate* sharing_message_delegate =
        sharing_message_bridge_.value()->GetControllerDelegate().get();
    controllers.push_back(std::make_unique<SharingMessageDataTypeController>(
        /*delegate_for_full_sync_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            sharing_message_delegate),
        /*delegate_for_transport_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            sharing_message_delegate)));
  }

  if (!disabled_types.Has(syncer::READING_LIST)) {
    // The transport-mode delegate may or may not be null depending on
    // platform and feature toggle state.
    syncer::DataTypeControllerDelegate* delegate_for_transport_mode =
        dual_reading_list_model_.value()
            ->GetSyncControllerDelegateForTransportMode()
            .get();

    controllers.push_back(std::make_unique<DataTypeController>(
        syncer::READING_LIST,
        /*delegate_for_full_sync_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            dual_reading_list_model_.value()
                ->GetSyncControllerDelegate()
                .get()),
        /*delegate_for_transport_mode=*/
        delegate_for_transport_mode
            ? std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                  delegate_for_transport_mode)
            : nullptr,
        std::make_unique<reading_list::ReadingListLocalDataBatchUploader>(
            dual_reading_list_model_.value())));
  }

  if (!disabled_types.Has(syncer::SEARCH_ENGINES) &&
      template_url_service_.value()) {
    controllers.push_back(
        std::make_unique<syncer::SyncableServiceBasedDataTypeController>(
            syncer::SEARCH_ENGINES,
            data_type_store_service_.value()->GetStoreFactory(),
            template_url_service_.value()->AsWeakPtr(), dump_stack,
            base::FeatureList::IsEnabled(
                syncer::kSeparateLocalAndAccountSearchEngines)
                ? syncer::SyncableServiceBasedDataTypeController::DelegateMode::
                      kTransportModeWithSingleModel
                : syncer::SyncableServiceBasedDataTypeController::DelegateMode::
                      kLegacyFullSyncModeOnly));
  }

  if (!disabled_types.Has(syncer::USER_EVENTS)) {
    syncer::DataTypeControllerDelegate* delegate =
        user_event_service_.value()->GetControllerDelegate().get();

    controllers.push_back(std::make_unique<syncer::UserEventDataTypeController>(
        sync_service,
        /*delegate_for_full_sync_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            delegate),
        /*delegate_for_transport_mode=*/
        base::FeatureList::IsEnabled(syncer::kReplaceSyncPromosWithSignInPromos)
            ? std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                  delegate)
            : nullptr));
  }

  if (!disabled_types.Has(syncer::SEND_TAB_TO_SELF)) {
    syncer::DataTypeControllerDelegate* delegate =
        send_tab_to_self_sync_service_.value()->GetControllerDelegate().get();
    controllers.push_back(
        std::make_unique<send_tab_to_self::SendTabToSelfDataTypeController>(
            /*delegate_for_full_sync_mode=*/
            std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                delegate),
            /*delegate_for_transport_mode=*/
            std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                delegate)));
  }

  if (!disabled_types.Has(syncer::USER_CONSENTS)) {
    syncer::DataTypeControllerDelegate* delegate =
        consent_auditor_.value()->GetControllerDelegate().get();

    // Forward both full-sync and transport-only modes to the same delegate,
    // since behavior for USER_CONSENTS does not differ (they are always
    // persisted).
    controllers.push_back(std::make_unique<DataTypeController>(
        syncer::USER_CONSENTS,
        /*delegate_for_full_sync_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            delegate),
        /*delegate_for_transport_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            delegate)));
  }

#if !BUILDFLAG(IS_IOS)
  if (!disabled_types.Has(syncer::AUTOFILL_VALUABLE) &&
      base::FeatureList::IsEnabled(syncer::kSyncAutofillLoyaltyCard)) {
    scoped_refptr<autofill::AutofillWebDataService> autofill_web_data_service =
        base::FeatureList::IsEnabled(syncer::kSyncMoveValuablesToProfileDb)
            ? profile_autofill_web_data_service_.value()
            : account_autofill_web_data_service_.value();
    controllers.push_back(
        std::make_unique<autofill::AutofillValuableDataTypeController>(
            syncer::AUTOFILL_VALUABLE,
            std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                autofill_web_data_service->GetDBTaskRunner(),
                base::BindRepeating(
                    &AutofillLoyaltyCardDelegateFromDataService,
                    base::RetainedRef(autofill_web_data_service))),
            std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                autofill_web_data_service->GetDBTaskRunner(),
                base::BindRepeating(
                    &AutofillLoyaltyCardDelegateFromDataService,
                    base::RetainedRef(autofill_web_data_service)))));
  }
#endif

  if (!disabled_types.Has(syncer::SHARED_TAB_GROUP_ACCOUNT_DATA) &&
      base::FeatureList::IsEnabled(syncer::kSyncSharedTabGroupAccountData) &&
      data_sharing_enabled) {
    syncer::DataTypeControllerDelegate* delegate = nullptr;
    if (personal_collaboration_data_service_.value()) {
      delegate = personal_collaboration_data_service_.value()
                     ->GetControllerDelegate()
                     .get();
    } else if (tab_group_sync_service_.value()) {
      delegate = tab_group_sync_service_.value()
                     ->GetSharedTabGroupAccountControllerDelegate()
                     .get();
    }

    if (delegate) {
      controllers.push_back(
          std::make_unique<
              collaboration::SharedTabGroupAccountDataTypeController>(
              /*delegate_for_full_sync_mode=*/
              std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                  delegate),
              /*delegate_for_transport_mode=*/
              std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                  delegate),
              sync_service, collaboration_service_.value()));
    }
  }

  if (!disabled_types.Has(syncer::SHARED_COMMENT) &&
      base::FeatureList::IsEnabled(syncer::kSyncSharedComment)) {
    // TODO(crbug.com/433556051): In a future CL, register the type, i.e.
    // instantiate the DataTypeController. There is more than one way to go
    // about it, but one option is:
    // - Create a trivial implementation of DataTypeSyncBridge which lives in
    //   your feature's directory. It should have synchronous access to your
    //   data model (e.g. DualReadingListModel) and be (indirectly) owned by a
    //   CoolKeyedService (often the model itself).
    // - Expose CoolKeyedService::GetControllerDelegate() which calls
    //   bridge->change_processor()->GetControllerDelegate().
    // - Inject CoolKeyedService in this class and call GetControllerDelegate()
    //   on it to create the DataTypeController.
    // In following CLs implement the bridge and keep adding unit tests.
  }

#if !BUILDFLAG(IS_ANDROID)
  if (!disabled_types.Has(syncer::WEBAUTHN_CREDENTIAL)) {
    syncer::DataTypeControllerDelegate* delegate =
        passkey_model_.value()->GetDataTypeControllerDelegate().get();

    controllers.push_back(std::make_unique<webauthn::PasskeyDataTypeController>(
        sync_service,
        /*delegate_for_full_sync_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            delegate),
        /*delegate_for_transport_mode=*/
        std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
            delegate)));
  }
#endif

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
  if (supervised_user_settings_service_.value()) {
    controllers.push_back(
        std::make_unique<SupervisedUserSettingsDataTypeController>(
            dump_stack, data_type_store_service_.value()->GetStoreFactory(),
            supervised_user_settings_service_.value()->AsWeakPtr(),
            pref_service_.value()));
  }
#endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)

  // `data_sharing_service_` is null on iOS WebView.
  if (data_sharing_service_.value() && data_sharing_enabled &&
      !disabled_types.Has(syncer::COLLABORATION_GROUP)) {
    syncer::DataTypeControllerDelegate* delegate =
        data_sharing_service_.value()
            ->GetCollaborationGroupControllerDelegate()
            .get();

    controllers.push_back(
        std::make_unique<collaboration::CollaborationGroupDataTypeController>(
            /*delegate_for_full_sync_mode=*/
            std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                delegate),
            /*delegate_for_transport_mode=*/
            std::make_unique<syncer::ForwardingDataTypeControllerDelegate>(
                delegate),
            sync_service, collaboration_service_.value()));
  }

  return controllers;
}

std::unique_ptr<DataTypeController>
CommonControllerBuilder::CreateWalletDataTypeController(
    syncer::DataType type,
    const base::RepeatingCallback<
        base::WeakPtr<syncer::DataTypeControllerDelegate>(
            autofill::AutofillWebDataService*)>& delegate_from_web_data,
    syncer::SyncService* sync_service,
    bool with_transport_mode_support) {
  // Transport mode should be supported, except for METADATA and OFFER where
  // support is still work in progress, see crbug.com/1448894 and
  // crbug.com/1448895.
  CHECK(with_transport_mode_support ||
        type == syncer::AUTOFILL_WALLET_METADATA ||
        type == syncer::AUTOFILL_WALLET_OFFER);
  auto delegate_for_full_sync_mode =
      std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
          profile_autofill_web_data_service_.value()->GetDBTaskRunner(),
          base::BindRepeating(
              delegate_from_web_data,
              base::RetainedRef(profile_autofill_web_data_service_.value())));
  auto delegate_for_transport_mode =
      with_transport_mode_support
          ? std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                account_autofill_web_data_service_.value()->GetDBTaskRunner(),
                base::BindRepeating(
                    delegate_from_web_data,
                    base::RetainedRef(
                        account_autofill_web_data_service_.value())))
          : nullptr;
  return std::make_unique<AutofillWalletDataTypeController>(
      type, std::move(delegate_for_full_sync_mode),
      std::move(delegate_for_transport_mode), pref_service_.value(),
      sync_service);
}

}  // namespace browser_sync
