// 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/non_ui_data_type_controller.h"

#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread.h"
#include "base/tracked_objects.h"
#include "components/sync_driver/data_type_controller_mock.h"
#include "components/sync_driver/fake_sync_client.h"
#include "components/sync_driver/generic_change_processor_factory.h"
#include "components/sync_driver/non_ui_data_type_controller_mock.h"
#include "sync/api/fake_syncable_service.h"
#include "sync/api/sync_change.h"
#include "sync/internal_api/public/engine/model_safe_worker.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace sync_driver {

class SyncClient;

namespace {

using base::WaitableEvent;
using syncer::AUTOFILL_PROFILE;
using testing::_;
using testing::AtLeast;
using testing::DoAll;
using testing::InvokeWithoutArgs;
using testing::Mock;
using testing::Return;
using testing::SetArgumentPointee;
using testing::StrictMock;

ACTION_P(WaitOnEvent, event) {
  event->Wait();
}

ACTION_P(SignalEvent, event) {
  event->Signal();
}

ACTION_P(SaveChangeProcessor, scoped_change_processor) {
  scoped_change_processor->reset(arg2);
}

ACTION_P(GetWeakPtrToSyncableService, syncable_service) {
  // Have to do this within an Action to ensure it's not evaluated on the wrong
  // thread.
  return syncable_service->AsWeakPtr();
}

class SharedChangeProcessorMock : public SharedChangeProcessor {
 public:
  SharedChangeProcessorMock() {}

  MOCK_METHOD6(Connect, base::WeakPtr<syncer::SyncableService>(
      SyncClient*,
      GenericChangeProcessorFactory*,
      syncer::UserShare*,
      DataTypeErrorHandler*,
      syncer::ModelType,
      const base::WeakPtr<syncer::SyncMergeResult>&));
  MOCK_METHOD0(Disconnect, bool());
  MOCK_METHOD2(ProcessSyncChanges,
               syncer::SyncError(const tracked_objects::Location&,
                         const syncer::SyncChangeList&));
  MOCK_CONST_METHOD2(GetAllSyncDataReturnError,
                     syncer::SyncError(syncer::ModelType,
                                       syncer::SyncDataList*));
  MOCK_METHOD0(GetSyncCount, int());
  MOCK_METHOD1(SyncModelHasUserCreatedNodes,
               bool(bool*));
  MOCK_METHOD0(CryptoReadyIfNecessary, bool());
  MOCK_CONST_METHOD1(GetDataTypeContext, bool(std::string*));

 protected:
  virtual ~SharedChangeProcessorMock() {}
  MOCK_METHOD2(OnUnrecoverableError, void(const tracked_objects::Location&,
                                          const std::string&));

 private:
  DISALLOW_COPY_AND_ASSIGN(SharedChangeProcessorMock);
};

class NonUIDataTypeControllerFake
    : public NonUIDataTypeController {
 public:
  NonUIDataTypeControllerFake(
      SyncClient* sync_client,
      NonUIDataTypeControllerMock* mock,
      SharedChangeProcessor* change_processor,
      scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner)
      : NonUIDataTypeController(base::ThreadTaskRunnerHandle::Get(),
                                base::Closure(),
                                sync_client),
        blocked_(false),
        mock_(mock),
        change_processor_(change_processor),
        backend_task_runner_(backend_task_runner) {}

  syncer::ModelType type() const override { return AUTOFILL_PROFILE; }
  syncer::ModelSafeGroup model_safe_group() const override {
    return syncer::GROUP_DB;
  }

  // Prevent tasks from being posted on the backend thread until
  // UnblockBackendTasks() is called.
  void BlockBackendTasks() {
    blocked_ = true;
  }

  // Post pending tasks on the backend thread and start allowing tasks
  // to be posted on the backend thread again.
  void UnblockBackendTasks() {
    blocked_ = false;
    for (std::vector<PendingTask>::const_iterator it = pending_tasks_.begin();
         it != pending_tasks_.end(); ++it) {
      PostTaskOnBackendThread(it->from_here, it->task);
    }
    pending_tasks_.clear();
  }

  SharedChangeProcessor* CreateSharedChangeProcessor() override {
    return change_processor_.get();
  }

 protected:
  bool PostTaskOnBackendThread(const tracked_objects::Location& from_here,
                               const base::Closure& task) override {
    if (blocked_) {
      pending_tasks_.push_back(PendingTask(from_here, task));
      return true;
    } else {
      return backend_task_runner_->PostTask(from_here, task);
    }
  }

  // We mock the following methods because their default implementations do
  // nothing, but we still want to make sure they're called appropriately.
  bool StartModels() override { return mock_->StartModels(); }
  void StopModels() override { mock_->StopModels(); }
  void RecordAssociationTime(base::TimeDelta time) override {
    mock_->RecordAssociationTime(time);
  }
  void RecordStartFailure(DataTypeController::ConfigureResult result) override {
    mock_->RecordStartFailure(result);
  }

 private:
  ~NonUIDataTypeControllerFake() override {}

  struct PendingTask {
    PendingTask(const tracked_objects::Location& from_here,
                const base::Closure& task)
        : from_here(from_here), task(task) {}

    tracked_objects::Location from_here;
    base::Closure task;
  };

  bool blocked_;
  std::vector<PendingTask> pending_tasks_;
  NonUIDataTypeControllerMock* mock_;
  scoped_refptr<SharedChangeProcessor> change_processor_;
  scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner_;

  DISALLOW_COPY_AND_ASSIGN(NonUIDataTypeControllerFake);
};

class SyncNonUIDataTypeControllerTest : public testing::Test,
                                        public FakeSyncClient {
 public:
  SyncNonUIDataTypeControllerTest()
      : backend_thread_("dbthread") {}

  void SetUp() override {
    backend_thread_.Start();
    change_processor_ = new SharedChangeProcessorMock();
    // All of these are refcounted, so don't need to be released.
    dtc_mock_ = new StrictMock<NonUIDataTypeControllerMock>();
    non_ui_dtc_ = new NonUIDataTypeControllerFake(
        this, dtc_mock_.get(), change_processor_.get(),
        backend_thread_.task_runner());
  }

  void TearDown() override { backend_thread_.Stop(); }

  void WaitForDTC() {
    WaitableEvent done(true, false);
    backend_thread_.task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&SyncNonUIDataTypeControllerTest::SignalDone, &done));
    done.TimedWait(TestTimeouts::action_timeout());
    if (!done.IsSignaled()) {
      ADD_FAILURE() << "Timed out waiting for DB thread to finish.";
    }
    base::MessageLoop::current()->RunUntilIdle();
  }

  SyncService* GetSyncService() override {
    // Make sure this isn't called on backend_thread.
    EXPECT_FALSE(backend_thread_.task_runner()->BelongsToCurrentThread());
    return FakeSyncClient::GetSyncService();
  }

 protected:
  void SetStartExpectations() {
    EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true));
    EXPECT_CALL(model_load_callback_, Run(_, _));
  }

  void SetAssociateExpectations() {
    EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
        .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
    EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
        .WillOnce(Return(true));
    EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_))
        .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true)));
    EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _))
        .WillOnce(Return(syncer::SyncError()));
    EXPECT_CALL(*change_processor_.get(), GetSyncCount()).WillOnce(Return(0));
    EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_));
  }

  void SetActivateExpectations(DataTypeController::ConfigureResult result) {
    EXPECT_CALL(start_callback_, Run(result, _, _));
  }

  void SetStopExpectations() {
    EXPECT_CALL(*dtc_mock_.get(), StopModels());
    EXPECT_CALL(*change_processor_.get(), Disconnect()).WillOnce(Return(true));
  }

  void SetStartFailExpectations(DataTypeController::ConfigureResult result) {
    EXPECT_CALL(*dtc_mock_.get(), StopModels()).Times(AtLeast(1));
    EXPECT_CALL(*dtc_mock_.get(), RecordStartFailure(result));
    EXPECT_CALL(start_callback_, Run(result, _, _));
  }

  void Start() {
    non_ui_dtc_->LoadModels(
        base::Bind(&ModelLoadCallbackMock::Run,
                   base::Unretained(&model_load_callback_)));
    non_ui_dtc_->StartAssociating(
        base::Bind(&StartCallbackMock::Run,
                   base::Unretained(&start_callback_)));
  }

  static void SignalDone(WaitableEvent* done) {
    done->Signal();
  }

  base::MessageLoopForUI message_loop_;
  base::Thread backend_thread_;

  StartCallbackMock start_callback_;
  ModelLoadCallbackMock model_load_callback_;
  // Must be destroyed after non_ui_dtc_.
  syncer::FakeSyncableService syncable_service_;
  scoped_refptr<NonUIDataTypeControllerFake> non_ui_dtc_;
  scoped_refptr<NonUIDataTypeControllerMock> dtc_mock_;
  scoped_refptr<SharedChangeProcessorMock> change_processor_;
  scoped_ptr<syncer::SyncChangeProcessor> saved_change_processor_;
};

TEST_F(SyncNonUIDataTypeControllerTest, StartOk) {
  SetStartExpectations();
  SetAssociateExpectations();
  SetActivateExpectations(DataTypeController::OK);
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state());
}

TEST_F(SyncNonUIDataTypeControllerTest, StartFirstRun) {
  SetStartExpectations();
  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
      .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
  EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
      .WillOnce(Return(true));
  EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true)));
  EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _))
      .WillOnce(Return(syncer::SyncError()));
  EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_));
  SetActivateExpectations(DataTypeController::OK_FIRST_RUN);
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state());
}

// Start the DTC and have StartModels() return false.  Then, stop the
// DTC without finishing model startup.  It should stop cleanly.
TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringStartModels) {
  EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(false));
  EXPECT_CALL(*dtc_mock_.get(), StopModels());
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  non_ui_dtc_->LoadModels(
      base::Bind(&ModelLoadCallbackMock::Run,
                 base::Unretained(&model_load_callback_)));
  WaitForDTC();
  EXPECT_EQ(DataTypeController::MODEL_STARTING, non_ui_dtc_->state());
  non_ui_dtc_->Stop();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
}

// Start the DTC and have MergeDataAndStartSyncing() return an error.
// The DTC should become disabled, and the DTC should still stop
// cleanly.
TEST_F(SyncNonUIDataTypeControllerTest, StartAssociationFailed) {
  SetStartExpectations();
  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
      .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
  EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
      .WillOnce(Return(true));
  EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true)));
  EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _))
      .WillOnce(Return(syncer::SyncError()));
  EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_));
  SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED);
  // Set up association to fail with an association failed error.
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  syncable_service_.set_merge_data_and_start_syncing_error(
      syncer::SyncError(FROM_HERE,
                        syncer::SyncError::DATATYPE_ERROR,
                        "Sync Error",
                        non_ui_dtc_->type()));
  Start();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::DISABLED, non_ui_dtc_->state());
  non_ui_dtc_->Stop();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
}

TEST_F(SyncNonUIDataTypeControllerTest,
       StartAssociationTriggersUnrecoverableError) {
  SetStartExpectations();
  SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR);
  // Set up association to fail with an unrecoverable error.
  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
      .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
  EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
      .WillRepeatedly(Return(true));
  EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_))
      .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false)));
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
}

TEST_F(SyncNonUIDataTypeControllerTest,
       StartAssociationCryptoNotReady) {
  SetStartExpectations();
  SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO);
  // Set up association to fail with a NEEDS_CRYPTO error.
  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
      .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
  EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
      .WillRepeatedly(Return(false));
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
}

// Trigger a Stop() call when we check if the model associator has user created
// nodes.
TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringAssociation) {
  WaitableEvent wait_for_db_thread_pause(false, false);
  WaitableEvent pause_db_thread(false, false);

  SetStartExpectations();
  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
      .WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
  EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary())
      .WillOnce(Return(true));
  EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_))
      .WillOnce(DoAll(SignalEvent(&wait_for_db_thread_pause),
                      WaitOnEvent(&pause_db_thread),
                      SetArgumentPointee<0>(true),
                      Return(true)));
  EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _))
      .WillOnce(
          Return(syncer::SyncError(FROM_HERE,
                                   syncer::SyncError::DATATYPE_ERROR,
                                   "Disconnected.",
                                   AUTOFILL_PROFILE)));
  EXPECT_CALL(*dtc_mock_.get(), StopModels());
  EXPECT_CALL(*change_processor_.get(), Disconnect())
      .WillOnce(DoAll(SignalEvent(&pause_db_thread), Return(true)));
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  wait_for_db_thread_pause.Wait();
  non_ui_dtc_->Stop();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
}

// Start the DTC while the backend tasks are blocked. Then stop the DTC before
// the backend tasks get a chance to run.
TEST_F(SyncNonUIDataTypeControllerTest, StartAfterSyncShutdown) {
  non_ui_dtc_->BlockBackendTasks();

  SetStartExpectations();
  // We don't expect StopSyncing to be called because local_service_ will never
  // have been set.
  SetStopExpectations();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  non_ui_dtc_->Stop();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Mock::VerifyAndClearExpectations(change_processor_.get());
  Mock::VerifyAndClearExpectations(dtc_mock_.get());

  EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _))
      .WillOnce(Return(base::WeakPtr<syncer::SyncableService>()));
  non_ui_dtc_->UnblockBackendTasks();
  WaitForDTC();
}

TEST_F(SyncNonUIDataTypeControllerTest, Stop) {
  SetStartExpectations();
  SetAssociateExpectations();
  SetActivateExpectations(DataTypeController::OK);
  SetStopExpectations();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state());
  non_ui_dtc_->Stop();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
}

// Start the DTC then block its backend tasks.  While its backend
// tasks are blocked, stop and start it again, then unblock its
// backend tasks.  The (delayed) running of the backend tasks from the
// stop after the restart shouldn't cause any problems.
TEST_F(SyncNonUIDataTypeControllerTest, StopStart) {
  SetStartExpectations();
  SetAssociateExpectations();
  SetActivateExpectations(DataTypeController::OK);
  SetStopExpectations();
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state());

  non_ui_dtc_->BlockBackendTasks();
  non_ui_dtc_->Stop();
  SetStartExpectations();
  SetAssociateExpectations();
  SetActivateExpectations(DataTypeController::OK);
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  non_ui_dtc_->UnblockBackendTasks();

  WaitForDTC();
  EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state());
}

TEST_F(SyncNonUIDataTypeControllerTest, OnSingleDataTypeUnrecoverableError) {
  SetStartExpectations();
  SetAssociateExpectations();
  SetActivateExpectations(DataTypeController::OK);
  EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state());
  Start();
  WaitForDTC();
  EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state());

  testing::Mock::VerifyAndClearExpectations(&start_callback_);
  EXPECT_CALL(model_load_callback_, Run(_, _));
  syncer::SyncError error(FROM_HERE,
                          syncer::SyncError::DATATYPE_ERROR,
                          "error",
                          non_ui_dtc_->type());
  backend_thread_.task_runner()->PostTask(
      FROM_HERE,
      base::Bind(
          &NonUIDataTypeControllerFake::OnSingleDataTypeUnrecoverableError,
          non_ui_dtc_.get(), error));
  WaitForDTC();
}

}  // namespace

}  // namespace sync_driver
