// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/browser_sync/profile_sync_components_factory_impl.h"

#include <utility>

#include "base/feature_list.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "build/build_config.h"
#include "components/autofill/core/browser/autofill_wallet_data_type_controller.h"
#include "components/autofill/core/browser/autofill_wallet_model_type_controller.h"
#include "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h"
#include "components/autofill/core/browser/webdata/autofill_profile_model_type_controller.h"
#include "components/autofill/core/browser/webdata/autofill_profile_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/browser_sync/browser_sync_switches.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/history/core/browser/sync/history_delete_directives_data_type_controller.h"
#include "components/history/core/browser/sync/history_delete_directives_model_type_controller.h"
#include "components/history/core/browser/sync/typed_url_model_type_controller.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/sync/password_data_type_controller.h"
#include "components/password_manager/core/browser/sync/password_syncable_service_based_model_type_controller.h"
#include "components/prefs/pref_service.h"
#include "components/reading_list/features/reading_list_switches.h"
#include "components/sync/base/report_unrecoverable_error.h"
#include "components/sync/device_info/local_device_info_provider_impl.h"
#include "components/sync/driver/async_directory_type_controller.h"
#include "components/sync/driver/data_type_manager_impl.h"
#include "components/sync/driver/glue/sync_backend_host_impl.h"
#include "components/sync/driver/model_type_controller.h"
#include "components/sync/driver/proxy_data_type_controller.h"
#include "components/sync/driver/sync_client.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/driver/syncable_service_based_model_type_controller.h"
#include "components/sync/engine/sync_engine.h"
#include "components/sync/model/model_type_store_service.h"
#include "components/sync/model_impl/forwarding_model_type_controller_delegate.h"
#include "components/sync/model_impl/proxy_model_type_controller_delegate.h"
#include "components/sync_bookmarks/bookmark_change_processor.h"
#include "components/sync_bookmarks/bookmark_data_type_controller.h"
#include "components/sync_bookmarks/bookmark_model_associator.h"
#include "components/sync_bookmarks/bookmark_sync_service.h"
#include "components/sync_sessions/session_data_type_controller.h"
#include "components/sync_sessions/session_model_type_controller.h"
#include "components/sync_sessions/session_sync_service.h"

using base::FeatureList;
using bookmarks::BookmarkModel;
using sync_bookmarks::BookmarkChangeProcessor;
using sync_bookmarks::BookmarkDataTypeController;
using sync_bookmarks::BookmarkModelAssociator;
using sync_sessions::SessionDataTypeController;
using syncer::AsyncDirectoryTypeController;
using syncer::DataTypeController;
using syncer::DataTypeManager;
using syncer::DataTypeManagerImpl;
using syncer::DataTypeManagerObserver;
using syncer::ModelTypeController;
using syncer::ProxyDataTypeController;
using syncer::SyncableServiceBasedModelTypeController;

namespace browser_sync {

namespace {

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

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

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

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

}  // namespace

ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl(
    syncer::SyncClient* sync_client,
    version_info::Channel channel,
    const std::string& version,
    bool is_tablet,
    const char* history_disabled_pref,
    const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
    const scoped_refptr<base::SingleThreadTaskRunner>& db_thread,
    const scoped_refptr<autofill::AutofillWebDataService>&
        web_data_service_on_disk,
    const scoped_refptr<autofill::AutofillWebDataService>&
        web_data_service_in_memory,
    const scoped_refptr<password_manager::PasswordStore>& password_store,
    sync_bookmarks::BookmarkSyncService* bookmark_sync_service)
    : sync_client_(sync_client),
      channel_(channel),
      version_(version),
      is_tablet_(is_tablet),
      history_disabled_pref_(history_disabled_pref),
      ui_thread_(ui_thread),
      db_thread_(db_thread),
      web_data_service_on_disk_(web_data_service_on_disk),
      web_data_service_in_memory_(web_data_service_in_memory),
      password_store_(password_store),
      bookmark_sync_service_(bookmark_sync_service) {}

ProfileSyncComponentsFactoryImpl::~ProfileSyncComponentsFactoryImpl() {}

syncer::DataTypeController::TypeVector
ProfileSyncComponentsFactoryImpl::CreateCommonDataTypeControllers(
    syncer::ModelTypeSet disabled_types,
    syncer::LocalDeviceInfoProvider* local_device_info_provider) {
  syncer::DataTypeController::TypeVector controllers;
  const base::RepeatingClosure dump_stack =
      base::BindRepeating(&syncer::ReportUnrecoverableError, channel_);

  // TODO(stanisc): can DEVICE_INFO be one of disabled datatypes?
  // Use an error callback that always uploads a stacktrace if it can to help
  // get USS as stable as possible.
  controllers.push_back(
      CreateModelTypeControllerForModelRunningOnUIThread(syncer::DEVICE_INFO));
  // These features are enabled only if there's a DB thread to post tasks to.
  if (db_thread_) {
    // Autocomplete sync is enabled by default.  Register unless explicitly
    // disabled.
    if (!disabled_types.Has(syncer::AUTOFILL)) {
      controllers.push_back(std::make_unique<ModelTypeController>(
          syncer::AUTOFILL,
          std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
              db_thread_, base::BindRepeating(
                              &AutocompleteDelegateFromDataService,
                              base::RetainedRef(web_data_service_on_disk_)))));
    }

    // Autofill sync is enabled by default.  Register unless explicitly
    // disabled.
    if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
      if (FeatureList::IsEnabled(switches::kSyncUSSAutofillProfile)) {
        controllers.push_back(
            std::make_unique<AutofillProfileModelTypeController>(
                std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
                    db_thread_,
                    base::BindRepeating(
                        &AutofillProfileDelegateFromDataService,
                        base::RetainedRef(web_data_service_on_disk_))),
                sync_client_));
      } else {
        controllers.push_back(
            std::make_unique<AutofillProfileDataTypeController>(
                db_thread_, dump_stack, sync_client_,
                web_data_service_on_disk_));
      }
    }

    // Wallet data sync is enabled by default, but behind a syncer experiment
    // enforced by the datatype controller. Register unless explicitly disabled.
    bool wallet_disabled = disabled_types.Has(syncer::AUTOFILL_WALLET_DATA);
    if (!wallet_disabled) {
      if (base::FeatureList::IsEnabled(switches::kSyncUSSAutofillWalletData)) {
        controllers.push_back(
            CreateWalletModelTypeControllerWithInMemorySupport(
                syncer::AUTOFILL_WALLET_DATA,
                base::BindRepeating(&AutofillWalletDelegateFromDataService)));
      } else {
        controllers.push_back(
            std::make_unique<AutofillWalletDataTypeController>(
                syncer::AUTOFILL_WALLET_DATA, db_thread_, dump_stack,
                sync_client_, web_data_service_on_disk_));
      }
    }

    // Wallet metadata sync depends on Wallet data sync. Register if Wallet data
    // is syncing and metadata sync is not explicitly disabled.
    if (!wallet_disabled &&
        !disabled_types.Has(syncer::AUTOFILL_WALLET_METADATA)) {
      if (base::FeatureList::IsEnabled(
              switches::kSyncUSSAutofillWalletMetadata)) {
        controllers.push_back(CreateWalletModelTypeController(
            syncer::AUTOFILL_WALLET_METADATA,
            base::BindRepeating(
                &AutofillWalletMetadataDelegateFromDataService)));
      } else {
        controllers.push_back(
            std::make_unique<AutofillWalletDataTypeController>(
                syncer::AUTOFILL_WALLET_METADATA, db_thread_, dump_stack,
                sync_client_, web_data_service_on_disk_));
      }
    }
  }

  // Bookmark sync is enabled by default.  Register unless explicitly
  // disabled.
  if (!disabled_types.Has(syncer::BOOKMARKS)) {
    if (FeatureList::IsEnabled(switches::kSyncUSSBookmarks)) {
      controllers.push_back(std::make_unique<ModelTypeController>(
          syncer::BOOKMARKS,
          std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
              ui_thread_,
              base::BindRepeating(&sync_bookmarks::BookmarkSyncService::
                                      GetBookmarkSyncControllerDelegate,
                                  base::Unretained(bookmark_sync_service_),
                                  sync_client_->GetFaviconService()))));
    } else {
      controllers.push_back(std::make_unique<BookmarkDataTypeController>(
          dump_stack, sync_client_));
    }
  }

  // These features are enabled only if history is not disabled.
  if (!sync_client_->GetPrefService()->GetBoolean(history_disabled_pref_)) {
    // TypedUrl sync is enabled by default.  Register unless explicitly
    // disabled.
    if (!disabled_types.Has(syncer::TYPED_URLS)) {
      // TypedURLModelTypeController uses a proxy delegate internally, as
      // provided by HistoryService.
      controllers.push_back(
          std::make_unique<history::TypedURLModelTypeController>(
              sync_client_->GetHistoryService(), sync_client_->GetPrefService(),
              history_disabled_pref_));
    }

    // Delete directive sync is enabled by default.
    if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
      if (base::FeatureList::IsEnabled(
              switches::kSyncPseudoUSSHistoryDeleteDirectives)) {
        controllers.push_back(
            std::make_unique<HistoryDeleteDirectivesModelTypeController>(
                dump_stack, sync_client_));

      } else {
        controllers.push_back(
            std::make_unique<HistoryDeleteDirectivesDataTypeController>(
                dump_stack, sync_client_));
      }
    }

    // Session sync is enabled by default.  This is disabled if history is
    // disabled because the tab sync data is added to the web history on the
    // server.
    if (!disabled_types.Has(syncer::PROXY_TABS)) {
      controllers.push_back(std::make_unique<ProxyDataTypeController>(
          syncer::PROXY_TABS,
          base::BindRepeating(
              &sync_sessions::SessionSyncService::ProxyTabsStateChanged,
              base::Unretained(sync_client_->GetSessionSyncService()))));
      if (FeatureList::IsEnabled(switches::kSyncUSSSessions)) {
        controllers.push_back(
            std::make_unique<sync_sessions::SessionModelTypeController>(
                sync_client_->GetPrefService(),
                std::make_unique<syncer::ForwardingModelTypeControllerDelegate>(
                    sync_client_->GetSessionSyncService()
                        ->GetControllerDelegate()
                        .get()),
                history_disabled_pref_));
      } else {
        controllers.push_back(std::make_unique<SessionDataTypeController>(
            dump_stack, sync_client_, local_device_info_provider,
            history_disabled_pref_));
      }
    }

    // Favicon sync is enabled by default. Register unless explicitly disabled.
    if (!disabled_types.Has(syncer::FAVICON_IMAGES) &&
        !disabled_types.Has(syncer::FAVICON_TRACKING)) {
      if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSFavicons)) {
        controllers.push_back(
            std::make_unique<SyncableServiceBasedModelTypeController>(
                syncer::FAVICON_IMAGES,
                sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
                base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType,
                               base::Unretained(sync_client_),
                               syncer::FAVICON_IMAGES),
                dump_stack));
        controllers.push_back(
            std::make_unique<SyncableServiceBasedModelTypeController>(
                syncer::FAVICON_TRACKING,
                sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
                base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType,
                               base::Unretained(sync_client_),
                               syncer::FAVICON_TRACKING),
                dump_stack));
      } else {
        controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
            syncer::FAVICON_IMAGES, base::RepeatingClosure(), sync_client_,
            syncer::GROUP_UI, ui_thread_));
        controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
            syncer::FAVICON_TRACKING, base::RepeatingClosure(), sync_client_,
            syncer::GROUP_UI, ui_thread_));
      }
    }
  }

  // Password sync is enabled by default.  Register unless explicitly
  // disabled.
  if (!disabled_types.Has(syncer::PASSWORDS)) {
    if (base::FeatureList::IsEnabled(switches::kSyncPseudoUSSPasswords)) {
      controllers.push_back(
          std::make_unique<password_manager::
                               PasswordSyncableServiceBasedModelTypeController>(
              sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
              dump_stack, password_store_, sync_client_));
    } else {
      controllers.push_back(std::make_unique<PasswordDataTypeController>(
          dump_stack, sync_client_,
          sync_client_->GetPasswordStateChangedCallback(), password_store_));
    }
  }

  if (!disabled_types.Has(syncer::PREFERENCES)) {
    if (override_prefs_controller_to_uss_for_test_) {
      controllers.push_back(CreateModelTypeControllerForModelRunningOnUIThread(
          syncer::PREFERENCES));
    } else if (base::FeatureList::IsEnabled(
                   switches::kSyncPseudoUSSPreferences)) {
      controllers.push_back(
          std::make_unique<SyncableServiceBasedModelTypeController>(
              syncer::PREFERENCES,
              sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
              base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType,
                             base::Unretained(sync_client_),
                             syncer::PREFERENCES),
              dump_stack));
    } else {
      controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
          syncer::PREFERENCES, dump_stack, sync_client_, syncer::GROUP_UI,
          ui_thread_));
    }
  }

  if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) {
    if (base::FeatureList::IsEnabled(
            switches::kSyncPseudoUSSPriorityPreferences)) {
      controllers.push_back(
          std::make_unique<SyncableServiceBasedModelTypeController>(
              syncer::PRIORITY_PREFERENCES,
              sync_client_->GetModelTypeStoreService()->GetStoreFactory(),
              base::BindOnce(&syncer::SyncClient::GetSyncableServiceForType,
                             base::Unretained(sync_client_),
                             syncer::PRIORITY_PREFERENCES),
              dump_stack));
    } else {
      controllers.push_back(std::make_unique<AsyncDirectoryTypeController>(
          syncer::PRIORITY_PREFERENCES, dump_stack, sync_client_,
          syncer::GROUP_UI, ui_thread_));
    }
  }

#if defined(OS_CHROMEOS)
  if (!disabled_types.Has(syncer::PRINTERS)) {
    controllers.push_back(
        CreateModelTypeControllerForModelRunningOnUIThread(syncer::PRINTERS));
  }
#endif

  // Reading list sync is enabled by default only on iOS. Register unless
  // Reading List or Reading List Sync is explicitly disabled.
  if (!disabled_types.Has(syncer::READING_LIST) &&
      reading_list::switches::IsReadingListEnabled()) {
    controllers.push_back(CreateModelTypeControllerForModelRunningOnUIThread(
        syncer::READING_LIST));
  }

  if (!disabled_types.Has(syncer::USER_EVENTS) &&
      FeatureList::IsEnabled(switches::kSyncUserEvents)) {
    controllers.push_back(CreateModelTypeControllerForModelRunningOnUIThread(
        syncer::USER_EVENTS));
  }

  if (base::FeatureList::IsEnabled(switches::kSyncUserConsentSeparateType)) {
    // Forward both on-disk and in-memory storage modes to the same delegate,
    // since behavior for USER_CONSENTS does not differ (they are always
    // persisted).
    // TODO(crbug.com/867801): Replace the proxy delegates below with a simpler
    // forwarding delegate that involves no posting of tasks.
    controllers.push_back(std::make_unique<ModelTypeController>(
        syncer::USER_CONSENTS,
        /*delegate_on_disk=*/
        std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
            ui_thread_,
            base::BindRepeating(
                &syncer::SyncClient::GetControllerDelegateForModelType,
                base::Unretained(sync_client_), syncer::USER_CONSENTS)),
        /*delegate_in_memory=*/
        std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
            ui_thread_,
            base::BindRepeating(
                &syncer::SyncClient::GetControllerDelegateForModelType,
                base::Unretained(sync_client_), syncer::USER_CONSENTS))));
  }

  return controllers;
}

std::unique_ptr<DataTypeManager>
ProfileSyncComponentsFactoryImpl::CreateDataTypeManager(
    syncer::ModelTypeSet initial_types,
    const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
        debug_info_listener,
    const DataTypeController::TypeMap* controllers,
    const syncer::DataTypeEncryptionHandler* encryption_handler,
    syncer::ModelTypeConfigurer* configurer,
    DataTypeManagerObserver* observer) {
  return std::make_unique<DataTypeManagerImpl>(
      sync_client_, initial_types, debug_info_listener, controllers,
      encryption_handler, configurer, observer);
}

std::unique_ptr<syncer::SyncEngine>
ProfileSyncComponentsFactoryImpl::CreateSyncEngine(
    const std::string& name,
    invalidation::InvalidationService* invalidator,
    const base::WeakPtr<syncer::SyncPrefs>& sync_prefs,
    const base::FilePath& sync_data_folder) {
  return std::make_unique<syncer::SyncBackendHostImpl>(
      name, sync_client_, invalidator, sync_prefs, sync_data_folder);
}

std::unique_ptr<syncer::LocalDeviceInfoProvider>
ProfileSyncComponentsFactoryImpl::CreateLocalDeviceInfoProvider() {
  return std::make_unique<syncer::LocalDeviceInfoProviderImpl>(
      channel_, version_, is_tablet_);
}

syncer::SyncApiComponentFactory::SyncComponents
ProfileSyncComponentsFactoryImpl::CreateBookmarkSyncComponents(
    std::unique_ptr<syncer::DataTypeErrorHandler> error_handler) {
  BookmarkModel* bookmark_model = sync_client_->GetBookmarkModel();
  syncer::UserShare* user_share =
      sync_client_->GetSyncService()->GetUserShare();
// TODO(akalin): We may want to propagate this switch up eventually.
#if defined(OS_ANDROID) || defined(OS_IOS)
  const bool kExpectMobileBookmarksFolder = true;
#else
  const bool kExpectMobileBookmarksFolder = false;
#endif

  auto model_associator = std::make_unique<BookmarkModelAssociator>(
      bookmark_model, sync_client_, user_share, error_handler->Copy(),
      kExpectMobileBookmarksFolder);

  SyncComponents components;
  components.change_processor = std::make_unique<BookmarkChangeProcessor>(
      sync_client_, model_associator.get(), std::move(error_handler));
  components.model_associator = std::move(model_associator);
  return components;
}

// static
void ProfileSyncComponentsFactoryImpl::OverridePrefsForUssTest(bool use_uss) {
  override_prefs_controller_to_uss_for_test_ = use_uss;
}

bool ProfileSyncComponentsFactoryImpl::
    override_prefs_controller_to_uss_for_test_ = false;

std::unique_ptr<ModelTypeController> ProfileSyncComponentsFactoryImpl::
    CreateModelTypeControllerForModelRunningOnUIThread(syncer::ModelType type) {
  // TODO(crbug.com/867801): Replace the proxy delegate below with a simpler
  // forwarding delegate that involves no posting of tasks.
  return std::make_unique<ModelTypeController>(
      type, std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
                ui_thread_,
                base::BindRepeating(
                    &syncer::SyncClient::GetControllerDelegateForModelType,
                    base::Unretained(sync_client_), type)));
}

std::unique_ptr<ModelTypeController>
ProfileSyncComponentsFactoryImpl::CreateWalletModelTypeController(
    syncer::ModelType type,
    const base::RepeatingCallback<
        base::WeakPtr<syncer::ModelTypeControllerDelegate>(
            autofill::AutofillWebDataService*)>& delegate_from_web_data) {
  return std::make_unique<AutofillWalletModelTypeController>(
      type,
      std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
          db_thread_,
          base::BindRepeating(delegate_from_web_data,
                              base::RetainedRef(web_data_service_on_disk_))),
      sync_client_);
}

std::unique_ptr<ModelTypeController> ProfileSyncComponentsFactoryImpl::
    CreateWalletModelTypeControllerWithInMemorySupport(
        syncer::ModelType type,
        const base::RepeatingCallback<
            base::WeakPtr<syncer::ModelTypeControllerDelegate>(
                autofill::AutofillWebDataService*)>& delegate_from_web_data) {
  return std::make_unique<AutofillWalletModelTypeController>(
      type, /*delegate_on_disk=*/
      std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
          db_thread_,
          base::BindRepeating(delegate_from_web_data,
                              base::RetainedRef(web_data_service_on_disk_))),
      /*delegate_in_memory=*/
      std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
          db_thread_,
          base::BindRepeating(delegate_from_web_data,
                              base::RetainedRef(web_data_service_in_memory_))),
      sync_client_);
}

}  // namespace browser_sync
