// 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 "sync/internal_api/sync_rollback_manager.h"

#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "sync/internal_api/public/read_node.h"
#include "sync/internal_api/public/read_transaction.h"
#include "sync/internal_api/public/sessions/sync_session_snapshot.h"
#include "sync/internal_api/public/test/test_internal_components_factory.h"
#include "sync/internal_api/public/write_node.h"
#include "sync/internal_api/public/write_transaction.h"
#include "sync/internal_api/sync_backup_manager.h"
#include "sync/syncable/entry.h"
#include "sync/test/engine/fake_model_worker.h"
#include "sync/test/test_directory_backing_store.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using ::testing::_;
using ::testing::DoDefault;
using ::testing::Invoke;
using ::testing::Truly;
using ::testing::WithArgs;

namespace syncer {

namespace {

class TestChangeDelegate : public SyncManager::ChangeDelegate {
 public:
  TestChangeDelegate() {
    ON_CALL(*this, OnChangesApplied(_, _, _, _))
        .WillByDefault(
            WithArgs<3>(Invoke(this,
                               &TestChangeDelegate::VerifyDeletes)));
  }

  void add_expected_delete(int64 v) {
    expected_deletes_.insert(v);
  }

  MOCK_METHOD4(OnChangesApplied,
               void(ModelType model_type,
                    int64 model_version,
                    const BaseTransaction* trans,
                    const ImmutableChangeRecordList& changes));
  MOCK_METHOD1(OnChangesComplete, void(ModelType model_type));

 private:
  void VerifyDeletes(const ImmutableChangeRecordList& changes) {
    std::set<int64> deleted;
    for (size_t i = 0; i < changes.Get().size(); ++i) {
      const ChangeRecord& change = (changes.Get())[i];
      EXPECT_EQ(ChangeRecord::ACTION_DELETE, change.action);
      EXPECT_TRUE(deleted.find(change.id) == deleted.end());
      deleted.insert(change.id);
    }
    EXPECT_TRUE(expected_deletes_ == deleted);
  }

  std::set<int64> expected_deletes_;
};

class SyncRollbackManagerTest : public testing::Test,
                                public SyncManager::Observer {
 protected:
  void SetUp() override {
    CHECK(temp_dir_.CreateUniqueTempDir());

    worker_ = new FakeModelWorker(GROUP_UI);
  }

  MOCK_METHOD1(OnSyncCycleCompleted,
               void(const sessions::SyncSessionSnapshot&));
  MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus));
  MOCK_METHOD4(OnInitializationComplete,
               void(const WeakHandle<JsBackend>&,
                    const WeakHandle<DataTypeDebugInfoListener>&,
                    bool, ModelTypeSet));
  MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&));
  MOCK_METHOD1(OnMigrationRequested, void(ModelTypeSet));;
  MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&));

  void OnConfigDone(bool success) {
    EXPECT_TRUE(success);
  }

  int64 CreateEntry(UserShare* user_share, ModelType type,
                    const std::string& client_tag) {
    WriteTransaction trans(FROM_HERE, user_share);
    WriteNode node(&trans);
    EXPECT_EQ(WriteNode::INIT_SUCCESS,
              node.InitUniqueByCreation(type, client_tag));
    return node.GetEntry()->GetMetahandle();
  }

  void InitManager(SyncManager* manager, ModelTypeSet types,
                   TestChangeDelegate* delegate,
                   InternalComponentsFactory::StorageOption storage_option) {
    manager_ = manager;
    types_ = types;

    EXPECT_CALL(*this, OnInitializationComplete(_, _, _, _))
        .WillOnce(WithArgs<2>(Invoke(this,
                                     &SyncRollbackManagerTest::HandleInit)));

    manager->AddObserver(this);

    base::RunLoop run_loop;
    SyncManager::InitArgs args;
    args.database_location = temp_dir_.path();
    args.service_url = GURL("https://example.com/");
    args.workers.push_back(worker_);
    args.change_delegate = delegate;

    InternalComponentsFactory::StorageOption storage_used;
    args.internal_components_factory.reset(new TestInternalComponentsFactory(
        InternalComponentsFactory::Switches(), storage_option, &storage_used));
    manager->Init(&args);
    EXPECT_EQ(storage_option, storage_used);
    loop_.PostTask(FROM_HERE, run_loop.QuitClosure());
    run_loop.Run();
  }

  // Create and persist an entry by unique tag in DB.
  void PrepopulateDb(ModelType type, const std::string& client_tag) {
    SyncBackupManager backup_manager;
    TestChangeDelegate delegate;
    InitManager(&backup_manager, ModelTypeSet(type), &delegate,
                InternalComponentsFactory::STORAGE_ON_DISK_DEFERRED);
    CreateEntry(backup_manager.GetUserShare(), type, client_tag);
    backup_manager.ShutdownOnSyncThread(SWITCH_MODE_SYNC);
  }

  // Verify entry with |client_tag| exists in sync directory.
  bool VerifyEntry(UserShare* user_share, ModelType type,
                   const std::string& client_tag) {
    ReadTransaction trans(FROM_HERE, user_share);
    ReadNode node(&trans);
    return BaseNode::INIT_OK == node.InitByClientTagLookup(type, client_tag);
  }

 private:
  void ConfigureSyncer() {
    manager_->ConfigureSyncer(
          CONFIGURE_REASON_NEW_CLIENT,
          types_,
          ModelTypeSet(), ModelTypeSet(), ModelTypeSet(),
          ModelSafeRoutingInfo(),
          base::Bind(&SyncRollbackManagerTest::OnConfigDone,
                     base::Unretained(this), true),
          base::Bind(&SyncRollbackManagerTest::OnConfigDone,
                     base::Unretained(this), false));
  }

  void HandleInit(bool success) {
    if (success) {
      loop_.PostTask(FROM_HERE,
                     base::Bind(&SyncRollbackManagerTest::ConfigureSyncer,
                                base::Unretained(this)));
    } else {
      manager_->ShutdownOnSyncThread(STOP_SYNC);
    }
  }

  base::ScopedTempDir temp_dir_;
  scoped_refptr<ModelSafeWorker> worker_;
  base::MessageLoop loop_;    // Needed for WeakHandle
  SyncManager* manager_;
  ModelTypeSet types_;
};

bool IsRollbackDoneAction(SyncProtocolError e) {
  return e.action == syncer::ROLLBACK_DONE;
}

TEST_F(SyncRollbackManagerTest, RollbackBasic) {
  PrepopulateDb(PREFERENCES, "pref1");

  TestChangeDelegate delegate;
  SyncRollbackManager rollback_manager;
  InitManager(&rollback_manager, ModelTypeSet(PREFERENCES), &delegate,
              InternalComponentsFactory::STORAGE_ON_DISK);

  // Simulate a new entry added during type initialization.
  int64 new_pref_id =
      CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2");

  delegate.add_expected_delete(new_pref_id);
  EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _))
      .Times(1)
      .WillOnce(DoDefault());
  EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1);
  EXPECT_CALL(*this, OnActionableError(Truly(IsRollbackDoneAction))).Times(1);

  ModelSafeRoutingInfo routing_info;
  routing_info[PREFERENCES] = GROUP_UI;
  rollback_manager.StartSyncingNormally(routing_info, base::Time());
}

TEST_F(SyncRollbackManagerTest, NoRollbackOfTypesNotBackedUp) {
  PrepopulateDb(PREFERENCES, "pref1");

  TestChangeDelegate delegate;
  SyncRollbackManager rollback_manager;
  InitManager(&rollback_manager, ModelTypeSet(PREFERENCES, APPS), &delegate,
              InternalComponentsFactory::STORAGE_ON_DISK);

  // Simulate new entry added during type initialization.
  int64 new_pref_id =
      CreateEntry(rollback_manager.GetUserShare(), PREFERENCES, "pref2");
  CreateEntry(rollback_manager.GetUserShare(), APPS, "app1");

  delegate.add_expected_delete(new_pref_id);
  EXPECT_CALL(delegate, OnChangesApplied(_, _, _, _))
      .Times(1)
      .WillOnce(DoDefault());
  EXPECT_CALL(delegate, OnChangesComplete(_)).Times(1);

  ModelSafeRoutingInfo routing_info;
  routing_info[PREFERENCES] = GROUP_UI;
  rollback_manager.StartSyncingNormally(routing_info, base::Time());

  // APP entry is still valid.
  EXPECT_TRUE(VerifyEntry(rollback_manager.GetUserShare(), APPS, "app1"));
}

TEST_F(SyncRollbackManagerTest, BackupDbNotChangedOnAbort) {
  PrepopulateDb(PREFERENCES, "pref1");

  TestChangeDelegate delegate;
  scoped_ptr<SyncRollbackManager> rollback_manager(
      new SyncRollbackManager);
  InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate,
              InternalComponentsFactory::STORAGE_ON_DISK);

  // Simulate a new entry added during type initialization.
  CreateEntry(rollback_manager->GetUserShare(), PREFERENCES, "pref2");

  // Manager was shut down before sync starts.
  rollback_manager->ShutdownOnSyncThread(STOP_SYNC);

  // Verify new entry was not persisted.
  rollback_manager.reset(new SyncRollbackManager);
  InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), &delegate,
              InternalComponentsFactory::STORAGE_ON_DISK);
  EXPECT_FALSE(VerifyEntry(rollback_manager->GetUserShare(), PREFERENCES,
                           "pref2"));
}

TEST_F(SyncRollbackManagerTest, OnInitializationFailure) {
  // Test graceful shutdown on initialization failure.
  scoped_ptr<SyncRollbackManager> rollback_manager(
      new SyncRollbackManager);
  InitManager(rollback_manager.get(), ModelTypeSet(PREFERENCES), NULL,
              InternalComponentsFactory::STORAGE_ON_DISK);
}

}  // anonymous namespace

}  // namespace syncer
