// 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 <vector>

#include "base/deferred_sequenced_task_runner.h"
#include "base/message_loop/message_loop.h"
#include "base/thread_task_runner_handle.h"
#include "sync/engine/model_type_sync_proxy_impl.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/sessions/model_type_registry.h"
#include "sync/test/engine/fake_model_worker.h"
#include "sync/test/engine/mock_nudge_handler.h"
#include "sync/test/engine/test_directory_setter_upper.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace syncer {

class ModelTypeRegistryTest : public ::testing::Test {
 public:
  ModelTypeRegistryTest();
  virtual void SetUp() override;
  virtual void TearDown() override;

  ModelTypeRegistry* registry();

  static DataTypeState MakeInitialDataTypeState(ModelType type) {
    DataTypeState state;
    state.progress_marker.set_data_type_id(
        GetSpecificsFieldNumberFromModelType(type));
    state.next_client_id = 0;
    return state;
  }

 private:
  syncable::Directory* directory();

  base::MessageLoop message_loop_;

  TestDirectorySetterUpper dir_maker_;
  std::vector<scoped_refptr<ModelSafeWorker> > workers_;
  scoped_ptr<ModelTypeRegistry> registry_;
  MockNudgeHandler mock_nudge_handler_;
};

ModelTypeRegistryTest::ModelTypeRegistryTest() {}

void ModelTypeRegistryTest::SetUp() {
  dir_maker_.SetUp();
  scoped_refptr<ModelSafeWorker> passive_worker(
      new FakeModelWorker(GROUP_PASSIVE));
  scoped_refptr<ModelSafeWorker> ui_worker(
      new FakeModelWorker(GROUP_UI));
  scoped_refptr<ModelSafeWorker> db_worker(
      new FakeModelWorker(GROUP_DB));
  workers_.push_back(passive_worker);
  workers_.push_back(ui_worker);
  workers_.push_back(db_worker);

  registry_.reset(
      new ModelTypeRegistry(workers_, directory(), &mock_nudge_handler_));
}

void ModelTypeRegistryTest::TearDown() {
  registry_.reset();
  workers_.clear();
  dir_maker_.TearDown();
}

ModelTypeRegistry* ModelTypeRegistryTest::registry() {
  return registry_.get();
}

syncable::Directory* ModelTypeRegistryTest::directory() {
  return dir_maker_.directory();
}

// Create some directory update handlers and commit contributors.
//
// We don't get to inspect any of the state we're modifying.  This test is
// useful only for detecting crashes or memory leaks.
TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Once) {
  ModelSafeRoutingInfo routing_info;
  routing_info.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
  routing_info.insert(std::make_pair(BOOKMARKS, GROUP_UI));
  routing_info.insert(std::make_pair(AUTOFILL, GROUP_DB));

  registry()->SetEnabledDirectoryTypes(routing_info);
}

// Try two different routing info settings.
//
// We don't get to inspect any of the state we're modifying.  This test is
// useful only for detecting crashes or memory leaks.
TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Repeatedly) {
  ModelSafeRoutingInfo routing_info1;
  routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
  routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_PASSIVE));
  routing_info1.insert(std::make_pair(AUTOFILL, GROUP_PASSIVE));

  registry()->SetEnabledDirectoryTypes(routing_info1);

  ModelSafeRoutingInfo routing_info2;
  routing_info2.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
  routing_info2.insert(std::make_pair(BOOKMARKS, GROUP_UI));
  routing_info2.insert(std::make_pair(AUTOFILL, GROUP_DB));

  registry()->SetEnabledDirectoryTypes(routing_info2);
}

// Test removing all types from the list.
//
// We don't get to inspect any of the state we're modifying.  This test is
// useful only for detecting crashes or memory leaks.
TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Clear) {
  ModelSafeRoutingInfo routing_info1;
  routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
  routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI));
  routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB));

  registry()->SetEnabledDirectoryTypes(routing_info1);

  ModelSafeRoutingInfo routing_info2;
  registry()->SetEnabledDirectoryTypes(routing_info2);
}

// Test disabling then re-enabling some directory types.
//
// We don't get to inspect any of the state we're modifying.  This test is
// useful only for detecting crashes or memory leaks.
TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_OffAndOn) {
  ModelSafeRoutingInfo routing_info1;
  routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
  routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI));
  routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB));

  registry()->SetEnabledDirectoryTypes(routing_info1);

  ModelSafeRoutingInfo routing_info2;
  registry()->SetEnabledDirectoryTypes(routing_info2);

  registry()->SetEnabledDirectoryTypes(routing_info1);
}

TEST_F(ModelTypeRegistryTest, NonBlockingTypes) {
  ModelTypeSyncProxyImpl themes_sync_proxy(syncer::THEMES);
  ModelTypeSyncProxyImpl sessions_sync_proxy(syncer::SESSIONS);
  scoped_refptr<base::DeferredSequencedTaskRunner> task_runner =
      new base::DeferredSequencedTaskRunner(
          base::ThreadTaskRunnerHandle::Get());

  EXPECT_TRUE(registry()->GetEnabledTypes().Empty());

  registry()->ConnectSyncTypeToWorker(syncer::THEMES,
                                      MakeInitialDataTypeState(THEMES),
                                      UpdateResponseDataList(),
                                      task_runner,
                                      themes_sync_proxy.AsWeakPtrForUI());
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(
      ModelTypeSet(syncer::THEMES)));

  registry()->ConnectSyncTypeToWorker(syncer::SESSIONS,
                                      MakeInitialDataTypeState(SESSIONS),
                                      UpdateResponseDataList(),
                                      task_runner,
                                      sessions_sync_proxy.AsWeakPtrForUI());
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(
      ModelTypeSet(syncer::THEMES, syncer::SESSIONS)));

  registry()->DisconnectSyncWorker(syncer::THEMES);
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(
      ModelTypeSet(syncer::SESSIONS)));

  // Allow ModelTypeRegistry destruction to delete the
  // Sessions' ModelTypeSyncWorker.
}

TEST_F(ModelTypeRegistryTest, NonBlockingTypesWithDirectoryTypes) {
  ModelTypeSyncProxyImpl themes_sync_proxy(syncer::THEMES);
  ModelTypeSyncProxyImpl sessions_sync_proxy(syncer::SESSIONS);
  scoped_refptr<base::DeferredSequencedTaskRunner> task_runner =
      new base::DeferredSequencedTaskRunner(
          base::ThreadTaskRunnerHandle::Get());

  ModelSafeRoutingInfo routing_info1;
  routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
  routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI));
  routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB));

  ModelTypeSet current_types;
  EXPECT_TRUE(registry()->GetEnabledTypes().Empty());

  // Add the themes non-blocking type.
  registry()->ConnectSyncTypeToWorker(syncer::THEMES,
                                      MakeInitialDataTypeState(THEMES),
                                      UpdateResponseDataList(),
                                      task_runner,
                                      themes_sync_proxy.AsWeakPtrForUI());
  current_types.Put(syncer::THEMES);
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));

  // Add some directory types.
  registry()->SetEnabledDirectoryTypes(routing_info1);
  current_types.PutAll(GetRoutingInfoTypes(routing_info1));
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));

  // Add sessions non-blocking type.
  registry()->ConnectSyncTypeToWorker(syncer::SESSIONS,
                                      MakeInitialDataTypeState(SESSIONS),
                                      UpdateResponseDataList(),
                                      task_runner,
                                      sessions_sync_proxy.AsWeakPtrForUI());
  current_types.Put(syncer::SESSIONS);
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));

  // Remove themes non-blocking type.
  registry()->DisconnectSyncWorker(syncer::THEMES);
  current_types.Remove(syncer::THEMES);
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));

  // Clear all directory types.
  ModelSafeRoutingInfo routing_info2;
  registry()->SetEnabledDirectoryTypes(routing_info2);
  current_types.RemoveAll(GetRoutingInfoTypes(routing_info1));
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));
}

TEST_F(ModelTypeRegistryTest, DeletionOrdering) {
  scoped_ptr<ModelTypeSyncProxyImpl> themes_sync_proxy(
      new ModelTypeSyncProxyImpl(syncer::THEMES));
  scoped_ptr<ModelTypeSyncProxyImpl> sessions_sync_proxy(
      new ModelTypeSyncProxyImpl(syncer::SESSIONS));
  scoped_refptr<base::DeferredSequencedTaskRunner> task_runner =
      new base::DeferredSequencedTaskRunner(
          base::ThreadTaskRunnerHandle::Get());

  EXPECT_TRUE(registry()->GetEnabledTypes().Empty());

  registry()->ConnectSyncTypeToWorker(syncer::THEMES,
                                      MakeInitialDataTypeState(THEMES),
                                      UpdateResponseDataList(),
                                      task_runner,
                                      themes_sync_proxy->AsWeakPtrForUI());
  registry()->ConnectSyncTypeToWorker(syncer::SESSIONS,
                                      MakeInitialDataTypeState(SESSIONS),
                                      UpdateResponseDataList(),
                                      task_runner,
                                      sessions_sync_proxy->AsWeakPtrForUI());
  EXPECT_TRUE(registry()->GetEnabledTypes().Equals(
      ModelTypeSet(syncer::THEMES, syncer::SESSIONS)));

  // Tear down themes processing, starting with the worker.
  registry()->DisconnectSyncWorker(syncer::THEMES);
  themes_sync_proxy.reset();

  // Tear down sessions processing, starting with the type sync proxy.
  sessions_sync_proxy.reset();
  registry()->DisconnectSyncWorker(syncer::SESSIONS);

  EXPECT_TRUE(registry()->GetEnabledTypes().Empty());
}

}  // namespace syncer
