// 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/account_settings/account_setting_service.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_metadata_sync_bridge.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/core/browser/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>
AutofillValuableDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::ValuableSyncBridge::FromWebDataService(service)
      ->change_processor()
      ->GetControllerDelegate();
}

base::WeakPtr<syncer::DataTypeControllerDelegate>
AutofillValuableMetadataDelegateFromDataService(
    autofill::AutofillWebDataService* service) {
  return autofill::ValuableMetadataSyncBridge::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::SetAccountSettingService(
    autofill::AccountSettingService* account_setting_service) {
  account_setting_service_.Set(account_setting_service);
}

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();
    if (autofill_web_data_service) {
      controllers.push_back(
          std::make_unique<autofill::AutofillValuableDataTypeController>(
              syncer::AUTOFILL_VALUABLE,
              std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                  autofill_web_data_service->GetDBTaskRunner(),
                  base::BindRepeating(
                      &AutofillValuableDelegateFromDataService,
                      base::RetainedRef(autofill_web_data_service))),
              std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                  autofill_web_data_service->GetDBTaskRunner(),
                  base::BindRepeating(
                      &AutofillValuableDelegateFromDataService,
                      base::RetainedRef(autofill_web_data_service)))));
    }
  }

  if (!disabled_types.Has(syncer::AUTOFILL_VALUABLE_METADATA) &&
      base::FeatureList::IsEnabled(syncer::kSyncAutofillValuableMetadata)) {
    // Both `AUTOFILL_VALUABLE` and `AUTOFILL_VALUABLE_METADATA` use the same
    // controller as they share the same behaviour.
    controllers.push_back(
        std::make_unique<autofill::AutofillValuableDataTypeController>(
            syncer::AUTOFILL_VALUABLE_METADATA,
            std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                profile_autofill_web_data_service_.value()->GetDBTaskRunner(),
                base::BindRepeating(
                    &AutofillValuableMetadataDelegateFromDataService,
                    base::RetainedRef(
                        profile_autofill_web_data_service_.value()))),
            std::make_unique<syncer::ProxyDataTypeControllerDelegate>(
                profile_autofill_web_data_service_.value()->GetDBTaskRunner(),
                base::BindRepeating(
                    &AutofillValuableMetadataDelegateFromDataService,
                    base::RetainedRef(
                        profile_autofill_web_data_service_.value())))));
  }

#endif

#if !BUILDFLAG(IS_IOS)
  if (!disabled_types.Has(syncer::ACCOUNT_SETTING) &&
      account_setting_service_.value() &&
      base::FeatureList::IsEnabled(syncer::kSyncAccountSettings)) {
    controllers.push_back(std::make_unique<DataTypeController>(
        syncer::ACCOUNT_SETTING,
        /*delegate_for_full_sync_mode=*/
        account_setting_service_.value()->GetSyncControllerDelegate(),
        /*delegate_for_transport_mode=*/
        account_setting_service_.value()->GetSyncControllerDelegate()));
  }
#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 (!disabled_types.Has(syncer::AI_THREAD) &&
      base::FeatureList::IsEnabled(syncer::kSyncAIThread)) {
    // TODO(crbug.com/445841720): In CL #4, 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 CLs #5, #6, ..., implement the bridge and keep adding unit tests.
  }

  if (!disabled_types.Has(syncer::CONTEXTUAL_TASK) &&
      base::FeatureList::IsEnabled(syncer::kSyncContextualTask)) {
    // TODO(crbug.com/445840788): In CL #4, 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 CLs #5, #6, ..., 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
