// Copyright 2014 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/sync/driver/async_directory_type_controller.h"

#include <utility>

#include "base/logging.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/sync/base/bind_to_task_runner.h"
#include "components/sync/base/data_type_histogram.h"
#include "components/sync/base/model_type.h"
#include "components/sync/driver/configure_context.h"
#include "components/sync/driver/generic_change_processor_factory.h"
#include "components/sync/driver/sync_api_component_factory.h"
#include "components/sync/driver/sync_client.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/model/data_type_error_handler_impl.h"
#include "components/sync/model/sync_error.h"
#include "components/sync/model/sync_merge_result.h"
#include "components/sync/model/syncable_service.h"

namespace syncer {

SharedChangeProcessor*
AsyncDirectoryTypeController::CreateSharedChangeProcessor() {
  return new SharedChangeProcessor(type());
}

AsyncDirectoryTypeController::AsyncDirectoryTypeController(
    ModelType type,
    const base::Closure& dump_stack,
    SyncService* sync_service,
    SyncClient* sync_client,
    ModelSafeGroup model_safe_group,
    scoped_refptr<base::SequencedTaskRunner> model_thread)
    : DirectoryDataTypeController(type,
                                  dump_stack,
                                  sync_service,
                                  model_safe_group),
      sync_client_(sync_client),
      user_share_(nullptr),
      processor_factory_(new GenericChangeProcessorFactory()),
      state_(NOT_RUNNING),
      model_thread_(std::move(model_thread)) {}

void AsyncDirectoryTypeController::LoadModels(
    const ConfigureContext& configure_context,
    const ModelLoadCallback& model_load_callback) {
  DCHECK(CalledOnValidThread());
  DCHECK_EQ(configure_context.storage_option, STORAGE_ON_DISK)
      << " for type " << ModelTypeToString(type());

  model_load_callback_ = model_load_callback;

  if (state() != NOT_RUNNING) {
    model_load_callback_.Run(type(),
                             SyncError(FROM_HERE, SyncError::DATATYPE_ERROR,
                                       "Model already running", type()));
    return;
  }

  state_ = MODEL_STARTING;
  // Since we can't be called multiple times before Stop() is called,
  // |shared_change_processor_| must be null here.
  DCHECK(!shared_change_processor_);
  shared_change_processor_ = CreateSharedChangeProcessor();
  DCHECK(shared_change_processor_);
  if (!StartModels()) {
    // If we are waiting for some external service to load before associating
    // or we failed to start the models, we exit early.
    DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING);
    return;
  }

  OnModelLoaded();
}

void AsyncDirectoryTypeController::OnModelLoaded() {
  DCHECK(CalledOnValidThread());
  DCHECK_EQ(state_, MODEL_STARTING);
  state_ = MODEL_LOADED;
  model_load_callback_.Run(type(), SyncError());
}

bool AsyncDirectoryTypeController::StartModels() {
  DCHECK(CalledOnValidThread());
  DCHECK_EQ(state_, MODEL_STARTING);
  // By default, no additional services need to be started before we can proceed
  // with model association.
  return true;
}

void AsyncDirectoryTypeController::StopModels() {
  DCHECK(CalledOnValidThread());
}

bool AsyncDirectoryTypeController::PostTaskOnModelThread(
    const base::Location& from_here,
    const base::Closure& task) {
  DCHECK(CalledOnValidThread());
  return model_thread_->PostTask(from_here, task);
}

void AsyncDirectoryTypeController::StartAssociating(
    StartCallback start_callback) {
  DCHECK(CalledOnValidThread());
  DCHECK(!start_callback.is_null());
  DCHECK_EQ(state_, MODEL_LOADED);
  state_ = ASSOCIATING;

  // Store UserShare now while on UI thread to avoid potential race
  // condition in StartAssociationWithSharedChangeProcessor.
  user_share_ = sync_service()->GetUserShare();

  start_callback_ = std::move(start_callback);
  if (!StartAssociationAsync()) {
    SyncError error(FROM_HERE, SyncError::DATATYPE_ERROR,
                    "Failed to post StartAssociation", type());
    SyncMergeResult local_merge_result(type());
    local_merge_result.set_error(error);
    StartDone(ASSOCIATION_FAILED, local_merge_result, SyncMergeResult(type()));
    // StartDone should have cleared the SharedChangeProcessor.
    DCHECK(!shared_change_processor_);
    return;
  }
}

void AsyncDirectoryTypeController::Stop(ShutdownReason shutdown_reason) {
  DCHECK(CalledOnValidThread());

  if (state() == NOT_RUNNING)
    return;

  // Disconnect the change processor. At this point, the
  // SyncableService can no longer interact with the Syncer, even if
  // it hasn't finished MergeDataAndStartSyncing.
  DisconnectSharedChangeProcessor();

  // If we haven't finished starting, we need to abort the start.
  bool service_started = state() == ASSOCIATING || state() == RUNNING;
  state_ = service_started ? STOPPING : NOT_RUNNING;
  StopModels();

  if (service_started)
    StopSyncableService();

  shared_change_processor_ = nullptr;
  state_ = NOT_RUNNING;
}

DataTypeController::State AsyncDirectoryTypeController::state() const {
  return state_;
}

void AsyncDirectoryTypeController::SetGenericChangeProcessorFactoryForTest(
    std::unique_ptr<GenericChangeProcessorFactory> factory) {
  DCHECK_EQ(state_, NOT_RUNNING);
  processor_factory_ = std::move(factory);
}

AsyncDirectoryTypeController::AsyncDirectoryTypeController()
    : DirectoryDataTypeController(UNSPECIFIED,
                                  base::Closure(),
                                  nullptr,
                                  GROUP_PASSIVE),
      sync_client_(nullptr) {}

AsyncDirectoryTypeController::~AsyncDirectoryTypeController() {}

void AsyncDirectoryTypeController::StartDone(
    DataTypeController::ConfigureResult start_result,
    const SyncMergeResult& local_merge_result,
    const SyncMergeResult& syncer_merge_result) {
  DCHECK(CalledOnValidThread());

  DataTypeController::State new_state;
  if (IsSuccessfulResult(start_result)) {
    new_state = RUNNING;
  } else {
    new_state = (start_result == ASSOCIATION_FAILED ? FAILED : NOT_RUNNING);
  }

  // If we failed to start up, and we haven't been stopped yet, we need to
  // ensure we clean up the local service and shared change processor properly.
  if (new_state != RUNNING && state() != NOT_RUNNING && state() != STOPPING) {
    DisconnectSharedChangeProcessor();
    StopSyncableService();
    shared_change_processor_ = nullptr;
  }

  // It's possible to have StartDone called first from the UI thread
  // (due to Stop being called) and then posted from the non-UI thread. In
  // this case, we drop the second call because we've already been stopped.
  if (state_ == NOT_RUNNING) {
    return;
  }

  state_ = new_state;
  if (state_ != RUNNING) {
    // Start failed.
    StopModels();
    RecordStartFailure(start_result);
  }

  std::move(start_callback_)
      .Run(start_result, local_merge_result, syncer_merge_result);
}

void AsyncDirectoryTypeController::RecordStartFailure(ConfigureResult result) {
  DCHECK(CalledOnValidThread());
  // TODO(wychen): enum uma should be strongly typed. crbug.com/661401
  UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures2",
                            ModelTypeToHistogramInt(type()),
                            static_cast<int>(MODEL_TYPE_COUNT));
#define PER_DATA_TYPE_MACRO(type_str)                                    \
  UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \
                            MAX_CONFIGURE_RESULT);
  SYNC_DATA_TYPE_HISTOGRAM(type());
#undef PER_DATA_TYPE_MACRO
}

void AsyncDirectoryTypeController::DisableImpl(const SyncError& error) {
  DCHECK(CalledOnValidThread());
  if (model_load_callback_) {
    model_load_callback_.Run(type(), error);
  }
}

bool AsyncDirectoryTypeController::StartAssociationAsync() {
  DCHECK(CalledOnValidThread());
  DCHECK_EQ(state(), ASSOCIATING);
  return PostTaskOnModelThread(
      FROM_HERE,
      base::Bind(
          &SharedChangeProcessor::StartAssociation, shared_change_processor_,
          BindToCurrentSequence(base::Bind(
              &AsyncDirectoryTypeController::StartDone, base::AsWeakPtr(this))),
          sync_client_, processor_factory_.get(), user_share_,
          base::Passed(CreateErrorHandler())));
}

ChangeProcessor* AsyncDirectoryTypeController::GetChangeProcessor() const {
  DCHECK(CalledOnValidThread());
  DCHECK_EQ(state_, RUNNING);
  return shared_change_processor_->generic_change_processor();
}

void AsyncDirectoryTypeController::DisconnectSharedChangeProcessor() {
  DCHECK(CalledOnValidThread());
  // |shared_change_processor_| can already be null if Stop() is
  // called after StartDone(_, FAILED, _).
  if (shared_change_processor_) {
    shared_change_processor_->Disconnect();
  }
}

void AsyncDirectoryTypeController::StopSyncableService() {
  DCHECK(CalledOnValidThread());
  if (shared_change_processor_) {
    PostTaskOnModelThread(FROM_HERE,
                          base::Bind(&SharedChangeProcessor::StopLocalService,
                                     shared_change_processor_));
  }
}

std::unique_ptr<DataTypeErrorHandler>
AsyncDirectoryTypeController::CreateErrorHandler() {
  DCHECK(CalledOnValidThread());
  return std::make_unique<DataTypeErrorHandlerImpl>(
      base::SequencedTaskRunnerHandle::Get(), dump_stack_,
      base::Bind(&AsyncDirectoryTypeController::DisableImpl,
                 base::AsWeakPtr(this)));
}

}  // namespace syncer
