// 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 <cstddef>
#include <map>
#include <set>
#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "components/invalidation/fake_invalidation_state_tracker.h"
#include "components/invalidation/push_client_channel.h"
#include "components/invalidation/sync_invalidation_listener.h"
#include "google/cacheinvalidation/include/invalidation-client.h"
#include "google/cacheinvalidation/include/types.h"
#include "jingle/notifier/listener/fake_push_client.h"
#include "sync/internal_api/public/util/weak_handle.h"
#include "sync/notifier/dropped_invalidation_tracker.h"
#include "sync/notifier/invalidation_util.h"
#include "sync/notifier/object_id_invalidation_map.h"
#include "sync/notifier/unacked_invalidation_set_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace syncer {

namespace {

using invalidation::AckHandle;
using invalidation::ObjectId;

const char kClientId[] = "client_id";
const char kClientInfo[] = "client_info";

const char kState[] = "state";
const char kNewState[] = "new_state";

const char kPayload1[] = "payload1";
const char kPayload2[] = "payload2";

const int64 kVersion1 = 1LL;
const int64 kVersion2 = 2LL;

const int kChromeSyncSourceId = 1004;

struct AckHandleLessThan {
  bool operator()(const AckHandle& lhs, const AckHandle& rhs) const {
    return lhs.handle_data() < rhs.handle_data();
  }
};

typedef std::set<AckHandle, AckHandleLessThan> AckHandleSet;

// Fake invalidation::InvalidationClient implementation that keeps
// track of registered IDs and acked handles.
class FakeInvalidationClient : public invalidation::InvalidationClient {
 public:
  FakeInvalidationClient() : started_(false) {}
  virtual ~FakeInvalidationClient() {}

  const ObjectIdSet& GetRegisteredIds() const {
    return registered_ids_;
  }

  void ClearAckedHandles() {
    acked_handles_.clear();
  }

  bool IsAckedHandle(const AckHandle& ack_handle) const {
    return (acked_handles_.find(ack_handle) != acked_handles_.end());
  }

  // invalidation::InvalidationClient implementation.

  virtual void Start() OVERRIDE {
    started_ = true;
  }

  virtual void Stop() OVERRIDE {
    started_ = false;
  }

  virtual void Register(const ObjectId& object_id) OVERRIDE {
    if (!started_) {
      ADD_FAILURE();
      return;
    }
    registered_ids_.insert(object_id);
  }

  virtual void Register(
      const invalidation::vector<ObjectId>& object_ids) OVERRIDE {
    if (!started_) {
      ADD_FAILURE();
      return;
    }
    registered_ids_.insert(object_ids.begin(), object_ids.end());
  }

  virtual void Unregister(const ObjectId& object_id) OVERRIDE {
    if (!started_) {
      ADD_FAILURE();
      return;
    }
    registered_ids_.erase(object_id);
  }

  virtual void Unregister(
      const invalidation::vector<ObjectId>& object_ids) OVERRIDE {
    if (!started_) {
      ADD_FAILURE();
      return;
    }
    for (invalidation::vector<ObjectId>::const_iterator
             it = object_ids.begin(); it != object_ids.end(); ++it) {
      registered_ids_.erase(*it);
    }
  }

  virtual void Acknowledge(const AckHandle& ack_handle) OVERRIDE {
    if (!started_) {
      ADD_FAILURE();
      return;
    }
    acked_handles_.insert(ack_handle);
  }

 private:
  bool started_;
  ObjectIdSet registered_ids_;
  AckHandleSet acked_handles_;
};

// Fake delegate tkat keeps track of invalidation counts, payloads,
// and state.
class FakeDelegate : public SyncInvalidationListener::Delegate {
 public:
  explicit FakeDelegate(SyncInvalidationListener* listener)
      : state_(TRANSIENT_INVALIDATION_ERROR),
        drop_handlers_deleter_(&drop_handlers_) {}
  virtual ~FakeDelegate() {}

  size_t GetInvalidationCount(const ObjectId& id) const {
    Map::const_iterator it = invalidations_.find(id);
    if (it == invalidations_.end()) {
      return 0;
    } else {
      return it->second.size();
    }
  }

  int64 GetVersion(const ObjectId& id) const {
    Map::const_iterator it = invalidations_.find(id);
    if (it == invalidations_.end()) {
      ADD_FAILURE() << "No invalidations for ID " << ObjectIdToString(id);
      return 0;
    } else {
      return it->second.back().version();
    }
  }

  std::string GetPayload(const ObjectId& id) const {
    Map::const_iterator it = invalidations_.find(id);
    if (it == invalidations_.end()) {
      ADD_FAILURE() << "No invalidations for ID " << ObjectIdToString(id);
      return 0;
    } else {
      return it->second.back().payload();
    }
  }

  bool IsUnknownVersion(const ObjectId& id) const {
    Map::const_iterator it = invalidations_.find(id);
    if (it == invalidations_.end()) {
      ADD_FAILURE() << "No invalidations for ID " << ObjectIdToString(id);
      return false;
    } else {
      return it->second.back().is_unknown_version();
    }
  }

  bool StartsWithUnknownVersion(const ObjectId& id) const {
    Map::const_iterator it = invalidations_.find(id);
    if (it == invalidations_.end()) {
      ADD_FAILURE() << "No invalidations for ID " << ObjectIdToString(id);
      return false;
    } else {
      return it->second.front().is_unknown_version();
    }
  }

  InvalidatorState GetInvalidatorState() const {
    return state_;
  }

  DroppedInvalidationTracker* GetDropTrackerForObject(const ObjectId& id) {
    DropHandlers::iterator it = drop_handlers_.find(id);
    if (it == drop_handlers_.end()) {
      drop_handlers_.insert(
          std::make_pair(id, new DroppedInvalidationTracker(id)));
      return drop_handlers_.find(id)->second;
    } else {
      return it->second;
    }
  }

  void AcknowledgeNthInvalidation(const ObjectId& id, size_t n) {
    List& list = invalidations_[id];
    List::iterator it = list.begin() + n;
    it->Acknowledge();
  }

  void AcknowledgeAll(const ObjectId& id) {
    List& list = invalidations_[id];
    for (List::iterator it = list.begin(); it != list.end(); ++it) {
      it->Acknowledge();
    }
  }

  void DropNthInvalidation(const ObjectId& id, size_t n) {
    DroppedInvalidationTracker* drop_tracker = GetDropTrackerForObject(id);
    List& list = invalidations_[id];
    List::iterator it = list.begin() + n;
    it->Drop(drop_tracker);
  }

  void RecoverFromDropEvent(const ObjectId& id) {
    DroppedInvalidationTracker* drop_tracker = GetDropTrackerForObject(id);
    drop_tracker->RecordRecoveryFromDropEvent();
  }

  // SyncInvalidationListener::Delegate implementation.
  virtual void OnInvalidate(
      const ObjectIdInvalidationMap& invalidation_map) OVERRIDE {
    ObjectIdSet ids = invalidation_map.GetObjectIds();
    for (ObjectIdSet::iterator it = ids.begin(); it != ids.end(); ++it) {
      const SingleObjectInvalidationSet& incoming =
          invalidation_map.ForObject(*it);
      List& list = invalidations_[*it];
      list.insert(list.end(), incoming.begin(), incoming.end());
    }
  }

  virtual void OnInvalidatorStateChange(InvalidatorState state) OVERRIDE {
    state_ = state;
  }

 private:
  typedef std::vector<Invalidation> List;
  typedef std::map<ObjectId, List, ObjectIdLessThan> Map;
  typedef std::map<ObjectId,
                   DroppedInvalidationTracker*,
                   ObjectIdLessThan> DropHandlers;

  Map invalidations_;
  InvalidatorState state_;
  DropHandlers drop_handlers_;
  STLValueDeleter<DropHandlers> drop_handlers_deleter_;
};

invalidation::InvalidationClient* CreateFakeInvalidationClient(
    FakeInvalidationClient** fake_invalidation_client,
    invalidation::SystemResources* resources,
    int client_type,
    const invalidation::string& client_name,
    const invalidation::string& application_name,
    invalidation::InvalidationListener* listener) {
  *fake_invalidation_client = new FakeInvalidationClient();
  return *fake_invalidation_client;
}

class SyncInvalidationListenerTest : public testing::Test {
 protected:
  SyncInvalidationListenerTest()
      : kBookmarksId_(kChromeSyncSourceId, "BOOKMARK"),
        kPreferencesId_(kChromeSyncSourceId, "PREFERENCE"),
        kExtensionsId_(kChromeSyncSourceId, "EXTENSION"),
        kAppsId_(kChromeSyncSourceId, "APP"),
        fake_push_client_(new notifier::FakePushClient()),
        fake_invalidation_client_(NULL),
        listener_(scoped_ptr<SyncNetworkChannel>(new PushClientChannel(
            scoped_ptr<notifier::PushClient>(fake_push_client_)))),
        fake_delegate_(&listener_) {}

  virtual void SetUp() {
    StartClient();

    registered_ids_.insert(kBookmarksId_);
    registered_ids_.insert(kPreferencesId_);
    listener_.UpdateRegisteredIds(registered_ids_);
  }

  virtual void TearDown() {
    StopClient();
  }

  // Restart client without re-registering IDs.
  void RestartClient() {
    StopClient();
    StartClient();
  }

  void StartClient() {
    fake_invalidation_client_ = NULL;
    listener_.Start(base::Bind(&CreateFakeInvalidationClient,
                               &fake_invalidation_client_),
                    kClientId, kClientInfo, kState,
                    fake_tracker_.GetSavedInvalidations(),
                    MakeWeakHandle(fake_tracker_.AsWeakPtr()),
                    &fake_delegate_);
    DCHECK(fake_invalidation_client_);
  }

  void StopClient() {
    // listener_.StopForTest() stops the invalidation scheduler, which
    // deletes any pending tasks without running them.  Some tasks
    // "run and delete" another task, so they must be run in order to
    // avoid leaking the inner task.  listener_.StopForTest() does not
    // schedule any tasks, so it's both necessary and sufficient to
    // drain the task queue before calling it.
    FlushPendingWrites();
    fake_invalidation_client_ = NULL;
    listener_.StopForTest();
  }

  size_t GetInvalidationCount(const ObjectId& id) const {
    return fake_delegate_.GetInvalidationCount(id);
  }

  int64 GetVersion(const ObjectId& id) const {
    return fake_delegate_.GetVersion(id);
  }

  std::string GetPayload(const ObjectId& id) const {
    return fake_delegate_.GetPayload(id);
  }

  bool IsUnknownVersion(const ObjectId& id) const {
    return fake_delegate_.IsUnknownVersion(id);
  }

  bool StartsWithUnknownVersion(const ObjectId& id) const {
    return fake_delegate_.StartsWithUnknownVersion(id);
  }

  void AcknowledgeNthInvalidation(const ObjectId& id, size_t n) {
    fake_delegate_.AcknowledgeNthInvalidation(id, n);
  }

  void DropNthInvalidation(const ObjectId& id, size_t n) {
    return fake_delegate_.DropNthInvalidation(id, n);
  }

  void RecoverFromDropEvent(const ObjectId& id) {
    return fake_delegate_.RecoverFromDropEvent(id);
  }

  void AcknowledgeAll(const ObjectId& id) {
    fake_delegate_.AcknowledgeAll(id);
  }

  InvalidatorState GetInvalidatorState() const {
    return fake_delegate_.GetInvalidatorState();
  }

  std::string GetInvalidatorClientId() const {
    return fake_tracker_.GetInvalidatorClientId();
  }

  std::string GetBootstrapData() const {
    return fake_tracker_.GetBootstrapData();
  }

  UnackedInvalidationsMap GetSavedInvalidations() {
    // Allow any queued writes to go through first.
    FlushPendingWrites();
    return fake_tracker_.GetSavedInvalidations();
  }

  SingleObjectInvalidationSet GetSavedInvalidationsForType(const ObjectId& id) {
    const UnackedInvalidationsMap& saved_state = GetSavedInvalidations();
    UnackedInvalidationsMap::const_iterator it =
        saved_state.find(kBookmarksId_);
    if (it == saved_state.end()) {
      ADD_FAILURE() << "No state saved for ID " << ObjectIdToString(id);
      return SingleObjectInvalidationSet();
    }
    ObjectIdInvalidationMap map;
    it->second.ExportInvalidations(WeakHandle<AckHandler>(), &map);
    if (map.Empty()) {
      return SingleObjectInvalidationSet();
    } else  {
      return map.ForObject(id);
    }
  }

  ObjectIdSet GetRegisteredIds() const {
    return fake_invalidation_client_->GetRegisteredIds();
  }

  // |payload| can be NULL.
  void FireInvalidate(const ObjectId& object_id,
                      int64 version, const char* payload) {
    invalidation::Invalidation inv;
    if (payload) {
      inv = invalidation::Invalidation(object_id, version, payload);
    } else {
      inv = invalidation::Invalidation(object_id, version);
    }
    const AckHandle ack_handle("fakedata");
    fake_invalidation_client_->ClearAckedHandles();
    listener_.Invalidate(fake_invalidation_client_, inv, ack_handle);
    EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle));
  }

  // |payload| can be NULL, but not |type_name|.
  void FireInvalidateUnknownVersion(const ObjectId& object_id) {
    const AckHandle ack_handle("fakedata_unknown");
    fake_invalidation_client_->ClearAckedHandles();
    listener_.InvalidateUnknownVersion(fake_invalidation_client_,
                                       object_id,
                                       ack_handle);
    EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle));
  }

  void FireInvalidateAll() {
    const AckHandle ack_handle("fakedata_all");
    fake_invalidation_client_->ClearAckedHandles();
    listener_.InvalidateAll(fake_invalidation_client_, ack_handle);
    EXPECT_TRUE(fake_invalidation_client_->IsAckedHandle(ack_handle));
  }

  void WriteState(const std::string& new_state) {
    listener_.WriteState(new_state);

    // Pump message loop to trigger
    // InvalidationStateTracker::WriteState().
    FlushPendingWrites();
  }

  void FlushPendingWrites() {
    message_loop_.RunUntilIdle();
  }

  void EnableNotifications() {
    fake_push_client_->EnableNotifications();
  }

  void DisableNotifications(notifier::NotificationsDisabledReason reason) {
    fake_push_client_->DisableNotifications(reason);
  }

  const ObjectId kBookmarksId_;
  const ObjectId kPreferencesId_;
  const ObjectId kExtensionsId_;
  const ObjectId kAppsId_;

  ObjectIdSet registered_ids_;

 private:
  base::MessageLoop message_loop_;
  notifier::FakePushClient* const fake_push_client_;

 protected:
  // A derrived test needs direct access to this.
  FakeInvalidationStateTracker fake_tracker_;

  // Tests need to access these directly.
  FakeInvalidationClient* fake_invalidation_client_;
  SyncInvalidationListener listener_;

 private:
  FakeDelegate fake_delegate_;
};

// Write a new state to the client.  It should propagate to the
// tracker.
TEST_F(SyncInvalidationListenerTest, WriteState) {
  WriteState(kNewState);

  EXPECT_EQ(kNewState, GetBootstrapData());
}

// Invalidation tests.

// Fire an invalidation without a payload.  It should be processed,
// the payload should remain empty, and the version should be updated.
TEST_F(SyncInvalidationListenerTest, InvalidateNoPayload) {
  const ObjectId& id = kBookmarksId_;

  FireInvalidate(id, kVersion1, NULL);

  ASSERT_EQ(1U, GetInvalidationCount(id));
  ASSERT_FALSE(IsUnknownVersion(id));
  EXPECT_EQ(kVersion1, GetVersion(id));
  EXPECT_EQ("", GetPayload(id));
}

// Fire an invalidation with an empty payload.  It should be
// processed, the payload should remain empty, and the version should
// be updated.
TEST_F(SyncInvalidationListenerTest, InvalidateEmptyPayload) {
  const ObjectId& id = kBookmarksId_;

  FireInvalidate(id, kVersion1, "");

  ASSERT_EQ(1U, GetInvalidationCount(id));
  ASSERT_FALSE(IsUnknownVersion(id));
  EXPECT_EQ(kVersion1, GetVersion(id));
  EXPECT_EQ("", GetPayload(id));
}

// Fire an invalidation with a payload.  It should be processed, and
// both the payload and the version should be updated.
TEST_F(SyncInvalidationListenerTest, InvalidateWithPayload) {
  const ObjectId& id = kPreferencesId_;

  FireInvalidate(id, kVersion1, kPayload1);

  ASSERT_EQ(1U, GetInvalidationCount(id));
  ASSERT_FALSE(IsUnknownVersion(id));
  EXPECT_EQ(kVersion1, GetVersion(id));
  EXPECT_EQ(kPayload1, GetPayload(id));
}

// Fire ten invalidations in a row.  All should be received.
TEST_F(SyncInvalidationListenerTest, ManyInvalidations_NoDrop) {
  const int kRepeatCount = 10;
  const ObjectId& id = kPreferencesId_;
  int64 initial_version = kVersion1;
  for (int64 i = initial_version; i < initial_version + kRepeatCount; ++i) {
    FireInvalidate(id, i, kPayload1);
  }
  ASSERT_EQ(static_cast<size_t>(kRepeatCount), GetInvalidationCount(id));
  ASSERT_FALSE(IsUnknownVersion(id));
  EXPECT_EQ(kPayload1, GetPayload(id));
  EXPECT_EQ(initial_version + kRepeatCount - 1, GetVersion(id));
}

// Fire an invalidation for an unregistered object ID with a payload.  It should
// still be processed, and both the payload and the version should be updated.
TEST_F(SyncInvalidationListenerTest, InvalidateBeforeRegistration_Simple) {
  const ObjectId kUnregisteredId(kChromeSyncSourceId, "unregistered");
  const ObjectId& id = kUnregisteredId;
  ObjectIdSet ids;
  ids.insert(id);

  EXPECT_EQ(0U, GetInvalidationCount(id));

  FireInvalidate(id, kVersion1, kPayload1);

  ASSERT_EQ(0U, GetInvalidationCount(id));

  EnableNotifications();
  listener_.Ready(fake_invalidation_client_);
  listener_.UpdateRegisteredIds(ids);

  ASSERT_EQ(1U, GetInvalidationCount(id));
  ASSERT_FALSE(IsUnknownVersion(id));
  EXPECT_EQ(kVersion1, GetVersion(id));
  EXPECT_EQ(kPayload1, GetPayload(id));
}

// Fire ten invalidations before an object registers.  Some invalidations will
// be dropped an replaced with an unknown version invalidation.
TEST_F(SyncInvalidationListenerTest, InvalidateBeforeRegistration_Drop) {
  const int kRepeatCount =
      UnackedInvalidationSet::kMaxBufferedInvalidations + 1;
  const ObjectId kUnregisteredId(kChromeSyncSourceId, "unregistered");
  const ObjectId& id = kUnregisteredId;
  ObjectIdSet ids;
  ids.insert(id);

  EXPECT_EQ(0U, GetInvalidationCount(id));

  int64 initial_version = kVersion1;
  for (int64 i = initial_version; i < initial_version + kRepeatCount; ++i) {
    FireInvalidate(id, i, kPayload1);
  }

  EnableNotifications();
  listener_.Ready(fake_invalidation_client_);
  listener_.UpdateRegisteredIds(ids);

  ASSERT_EQ(UnackedInvalidationSet::kMaxBufferedInvalidations,
            GetInvalidationCount(id));
  ASSERT_FALSE(IsUnknownVersion(id));
  EXPECT_EQ(initial_version + kRepeatCount - 1, GetVersion(id));
  EXPECT_EQ(kPayload1, GetPayload(id));
  EXPECT_TRUE(StartsWithUnknownVersion(id));
}

// Fire an invalidation, then fire another one with a lower version.  Both
// should be received.
TEST_F(SyncInvalidationListenerTest, InvalidateVersion) {
  const ObjectId& id = kPreferencesId_;

  FireInvalidate(id, kVersion2, kPayload2);

  ASSERT_EQ(1U, GetInvalidationCount(id));
  ASSERT_FALSE(IsUnknownVersion(id));
  EXPECT_EQ(kVersion2, GetVersion(id));
  EXPECT_EQ(kPayload2, GetPayload(id));

  FireInvalidate(id, kVersion1, kPayload1);

  ASSERT_EQ(2U, GetInvalidationCount(id));
  ASSERT_FALSE(IsUnknownVersion(id));

  EXPECT_EQ(kVersion1, GetVersion(id));
  EXPECT_EQ(kPayload1, GetPayload(id));
}

// Fire an invalidation with an unknown version.
TEST_F(SyncInvalidationListenerTest, InvalidateUnknownVersion) {
  const ObjectId& id = kBookmarksId_;

  FireInvalidateUnknownVersion(id);

  ASSERT_EQ(1U, GetInvalidationCount(id));
  EXPECT_TRUE(IsUnknownVersion(id));
}

// Fire an invalidation for all enabled IDs.
TEST_F(SyncInvalidationListenerTest, InvalidateAll) {
  FireInvalidateAll();

  for (ObjectIdSet::const_iterator it = registered_ids_.begin();
       it != registered_ids_.end(); ++it) {
    ASSERT_EQ(1U, GetInvalidationCount(*it));
    EXPECT_TRUE(IsUnknownVersion(*it));
  }
}

// Test a simple scenario for multiple IDs.
TEST_F(SyncInvalidationListenerTest, InvalidateMultipleIds) {
  FireInvalidate(kBookmarksId_, 3, NULL);

  ASSERT_EQ(1U, GetInvalidationCount(kBookmarksId_));
  ASSERT_FALSE(IsUnknownVersion(kBookmarksId_));
  EXPECT_EQ(3, GetVersion(kBookmarksId_));
  EXPECT_EQ("", GetPayload(kBookmarksId_));

  // kExtensionId is not registered, so the invalidation should not get through.
  FireInvalidate(kExtensionsId_, 2, NULL);
  ASSERT_EQ(0U, GetInvalidationCount(kExtensionsId_));
}

// Registration tests.

// With IDs already registered, enable notifications then ready the
// client.  The IDs should be registered only after the client is
// readied.
TEST_F(SyncInvalidationListenerTest, RegisterEnableReady) {
  EXPECT_TRUE(GetRegisteredIds().empty());

  EnableNotifications();

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(registered_ids_, GetRegisteredIds());
}

// With IDs already registered, ready the client then enable
// notifications.  The IDs should be registered after the client is
// readied.
TEST_F(SyncInvalidationListenerTest, RegisterReadyEnable) {
  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(registered_ids_, GetRegisteredIds());

  EnableNotifications();

  EXPECT_EQ(registered_ids_, GetRegisteredIds());
}

// Unregister the IDs, enable notifications, re-register the IDs, then
// ready the client.  The IDs should be registered only after the
// client is readied.
TEST_F(SyncInvalidationListenerTest, EnableRegisterReady) {
  listener_.UpdateRegisteredIds(ObjectIdSet());

  EXPECT_TRUE(GetRegisteredIds().empty());

  EnableNotifications();

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.UpdateRegisteredIds(registered_ids_);

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(registered_ids_, GetRegisteredIds());
}

// Unregister the IDs, enable notifications, ready the client, then
// re-register the IDs.  The IDs should be registered only after the
// client is readied.
TEST_F(SyncInvalidationListenerTest, EnableReadyRegister) {
  listener_.UpdateRegisteredIds(ObjectIdSet());

  EXPECT_TRUE(GetRegisteredIds().empty());

  EnableNotifications();

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.UpdateRegisteredIds(registered_ids_);

  EXPECT_EQ(registered_ids_, GetRegisteredIds());
}

// Unregister the IDs, ready the client, enable notifications, then
// re-register the IDs.  The IDs should be registered only after the
// client is readied.
TEST_F(SyncInvalidationListenerTest, ReadyEnableRegister) {
  listener_.UpdateRegisteredIds(ObjectIdSet());

  EXPECT_TRUE(GetRegisteredIds().empty());

  EnableNotifications();

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.UpdateRegisteredIds(registered_ids_);

  EXPECT_EQ(registered_ids_, GetRegisteredIds());
}

// Unregister the IDs, ready the client, re-register the IDs, then
// enable notifications. The IDs should be registered only after the
// client is readied.
//
// This test is important: see http://crbug.com/139424.
TEST_F(SyncInvalidationListenerTest, ReadyRegisterEnable) {
  listener_.UpdateRegisteredIds(ObjectIdSet());

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.UpdateRegisteredIds(registered_ids_);

  EXPECT_EQ(registered_ids_, GetRegisteredIds());

  EnableNotifications();

  EXPECT_EQ(registered_ids_, GetRegisteredIds());
}

// With IDs already registered, ready the client, restart the client,
// then re-ready it.  The IDs should still be registered.
TEST_F(SyncInvalidationListenerTest, RegisterTypesPreserved) {
  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(registered_ids_, GetRegisteredIds());

  RestartClient();

  EXPECT_TRUE(GetRegisteredIds().empty());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(registered_ids_, GetRegisteredIds());
}

// Make sure that state is correctly purged from the local invalidation state
// map cache when an ID is unregistered.
TEST_F(SyncInvalidationListenerTest, UnregisterCleansUpStateMapCache) {
  const ObjectId& id = kBookmarksId_;
  listener_.Ready(fake_invalidation_client_);

  EXPECT_TRUE(GetSavedInvalidations().empty());
  FireInvalidate(id, 1, "hello");
  EXPECT_EQ(1U, GetSavedInvalidations().size());
  EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id));
  FireInvalidate(kPreferencesId_, 2, "world");
  EXPECT_EQ(2U, GetSavedInvalidations().size());

  EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id));
  EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), kPreferencesId_));

  ObjectIdSet ids;
  ids.insert(id);
  listener_.UpdateRegisteredIds(ids);
  EXPECT_EQ(1U, GetSavedInvalidations().size());
  EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id));
}

TEST_F(SyncInvalidationListenerTest, DuplicateInvaldiations_Simple) {
  const ObjectId& id = kBookmarksId_;
  listener_.Ready(fake_invalidation_client_);

  // Send a stream of invalidations, including two copies of the second.
  FireInvalidate(id, 1, "one");
  FireInvalidate(id, 2, "two");
  FireInvalidate(id, 3, "three");
  FireInvalidate(id, 2, "two");

  // Expect that the duplicate was discarded.
  SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
  EXPECT_EQ(3U, list.GetSize());
  SingleObjectInvalidationSet::const_iterator it = list.begin();
  EXPECT_EQ(1, it->version());
  it++;
  EXPECT_EQ(2, it->version());
  it++;
  EXPECT_EQ(3, it->version());
}

TEST_F(SyncInvalidationListenerTest, DuplicateInvalidations_NearBufferLimit) {
  const size_t kPairsToSend = UnackedInvalidationSet::kMaxBufferedInvalidations;
  const ObjectId& id = kBookmarksId_;
  listener_.Ready(fake_invalidation_client_);

  // We will have enough buffer space in the state tracker for all these
  // invalidations only if duplicates are ignored.
  for (size_t i = 0; i < kPairsToSend; ++i) {
    FireInvalidate(id, i, "payload");
    FireInvalidate(id, i, "payload");
  }

  // Expect that the state map ignored duplicates.
  SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
  EXPECT_EQ(kPairsToSend, list.GetSize());
  EXPECT_FALSE(list.begin()->is_unknown_version());

  // Expect that all invalidations (including duplicates) were emitted.
  EXPECT_EQ(kPairsToSend*2, GetInvalidationCount(id));

  // Acknowledge all invalidations to clear the internal state.
  AcknowledgeAll(id);
  EXPECT_TRUE(GetSavedInvalidationsForType(id).IsEmpty());
}

TEST_F(SyncInvalidationListenerTest, DuplicateInvalidations_UnknownVersion) {
  const ObjectId& id = kBookmarksId_;
  listener_.Ready(fake_invalidation_client_);

  FireInvalidateUnknownVersion(id);
  FireInvalidateUnknownVersion(id);

  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    EXPECT_EQ(1U, list.GetSize());
  }

  // Acknowledge the second.  There should be no effect on the stored list.
  ASSERT_EQ(2U, GetInvalidationCount(id));
  AcknowledgeNthInvalidation(id, 1);
  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    EXPECT_EQ(1U, list.GetSize());
  }

  // Acknowledge the first.  This should remove the invalidation from the list.
  ASSERT_EQ(2U, GetInvalidationCount(id));
  AcknowledgeNthInvalidation(id, 0);
  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    EXPECT_EQ(0U, list.GetSize());
  }
}

// Make sure that acknowledgements erase items from the local store.
TEST_F(SyncInvalidationListenerTest, AcknowledgementsCleanUpStateMapCache) {
  const ObjectId& id = kBookmarksId_;
  listener_.Ready(fake_invalidation_client_);

  EXPECT_TRUE(GetSavedInvalidations().empty());
  FireInvalidate(id, 10, "hello");
  FireInvalidate(id, 20, "world");
  FireInvalidateUnknownVersion(id);

  // Expect that all three invalidations have been saved to permanent storage.
  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    ASSERT_EQ(3U, list.GetSize());
    EXPECT_TRUE(list.begin()->is_unknown_version());
    EXPECT_EQ(20, list.back().version());
  }

  // Acknowledge the second sent invaldiation (version 20) and verify it was
  // removed from storage.
  AcknowledgeNthInvalidation(id, 1);
  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    ASSERT_EQ(2U, list.GetSize());
    EXPECT_TRUE(list.begin()->is_unknown_version());
    EXPECT_EQ(10, list.back().version());
  }

  // Acknowledge the last sent invalidation (unknown version) and verify it was
  // removed from storage.
  AcknowledgeNthInvalidation(id, 2);
  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    ASSERT_EQ(1U, list.GetSize());
    EXPECT_FALSE(list.begin()->is_unknown_version());
    EXPECT_EQ(10, list.back().version());
  }
}

// Make sure that drops erase items from the local store.
TEST_F(SyncInvalidationListenerTest, DropsCleanUpStateMapCache) {
  const ObjectId& id = kBookmarksId_;
  listener_.Ready(fake_invalidation_client_);

  EXPECT_TRUE(GetSavedInvalidations().empty());
  FireInvalidate(id, 10, "hello");
  FireInvalidate(id, 20, "world");
  FireInvalidateUnknownVersion(id);

  // Expect that all three invalidations have been saved to permanent storage.
  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    ASSERT_EQ(3U, list.GetSize());
    EXPECT_TRUE(list.begin()->is_unknown_version());
    EXPECT_EQ(20, list.back().version());
  }

  // Drop the second sent invalidation (version 20) and verify it was removed
  // from storage.  Also verify we still have an unknown version invalidation.
  DropNthInvalidation(id, 1);
  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    ASSERT_EQ(2U, list.GetSize());
    EXPECT_TRUE(list.begin()->is_unknown_version());
    EXPECT_EQ(10, list.back().version());
  }

  // Drop the remaining invalidation.  Verify an unknown version is all that
  // remains.
  DropNthInvalidation(id, 0);
  {
    SingleObjectInvalidationSet list = GetSavedInvalidationsForType(id);
    ASSERT_EQ(1U, list.GetSize());
    EXPECT_TRUE(list.begin()->is_unknown_version());
  }

  // Announce that the delegate has recovered from the drop.  Verify no
  // invalidations remain saved.
  RecoverFromDropEvent(id);
  EXPECT_TRUE(GetSavedInvalidationsForType(id).IsEmpty());

  RecoverFromDropEvent(id);
}

// Without readying the client, disable notifications, then enable
// them.  The listener should still think notifications are disabled.
TEST_F(SyncInvalidationListenerTest, EnableNotificationsNotReady) {
  EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR,
            GetInvalidatorState());

  DisableNotifications(
      notifier::TRANSIENT_NOTIFICATION_ERROR);

  EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());

  DisableNotifications(notifier::NOTIFICATION_CREDENTIALS_REJECTED);

  EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState());

  EnableNotifications();

  EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());
}

// Enable notifications then Ready the invalidation client.  The
// delegate should then be ready.
TEST_F(SyncInvalidationListenerTest, EnableNotificationsThenReady) {
  EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());

  EnableNotifications();

  EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());
}

// Ready the invalidation client then enable notifications.  The
// delegate should then be ready.
TEST_F(SyncInvalidationListenerTest, ReadyThenEnableNotifications) {
  EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR, GetInvalidatorState());

  EnableNotifications();

  EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());
}

// Enable notifications and ready the client.  Then disable
// notifications with an auth error and re-enable notifications.  The
// delegate should go into an auth error mode and then back out.
TEST_F(SyncInvalidationListenerTest, PushClientAuthError) {
  EnableNotifications();
  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());

  DisableNotifications(
      notifier::NOTIFICATION_CREDENTIALS_REJECTED);

  EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState());

  EnableNotifications();

  EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());
}

// Enable notifications and ready the client.  Then simulate an auth
// error from the invalidation client.  Simulate some notification
// events, then re-ready the client.  The delegate should go into an
// auth error mode and come out of it only after the client is ready.
TEST_F(SyncInvalidationListenerTest, InvalidationClientAuthError) {
  EnableNotifications();
  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());

  listener_.InformError(
      fake_invalidation_client_,
      invalidation::ErrorInfo(
          invalidation::ErrorReason::AUTH_FAILURE,
          false /* is_transient */,
          "auth error",
          invalidation::ErrorContext()));

  EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState());

  DisableNotifications(notifier::TRANSIENT_NOTIFICATION_ERROR);

  EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState());

  DisableNotifications(notifier::TRANSIENT_NOTIFICATION_ERROR);

  EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState());

  EnableNotifications();

  EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED, GetInvalidatorState());

  listener_.Ready(fake_invalidation_client_);

  EXPECT_EQ(INVALIDATIONS_ENABLED, GetInvalidatorState());
}

// A variant of SyncInvalidationListenerTest that starts with some initial
// state.  We make not attempt to abstract away the contents of this state.  The
// tests that make use of this harness depend on its implementation details.
class SyncInvalidationListenerTest_WithInitialState
    : public SyncInvalidationListenerTest {
 public:
  virtual void SetUp() {
    UnackedInvalidationSet bm_state(kBookmarksId_);
    UnackedInvalidationSet ext_state(kExtensionsId_);

    Invalidation bm_unknown = Invalidation::InitUnknownVersion(kBookmarksId_);
    Invalidation bm_v100 = Invalidation::Init(kBookmarksId_, 100, "hundred");
    bm_state.Add(bm_unknown);
    bm_state.Add(bm_v100);

    Invalidation ext_v10 = Invalidation::Init(kExtensionsId_, 10, "ten");
    Invalidation ext_v20 = Invalidation::Init(kExtensionsId_, 20, "twenty");
    ext_state.Add(ext_v10);
    ext_state.Add(ext_v20);

    initial_state.insert(std::make_pair(kBookmarksId_, bm_state));
    initial_state.insert(std::make_pair(kExtensionsId_, ext_state));

    fake_tracker_.SetSavedInvalidations(initial_state);

    SyncInvalidationListenerTest::SetUp();
  }

  UnackedInvalidationsMap initial_state;
};

// Verify that saved invalidations are forwarded when handlers register.
TEST_F(SyncInvalidationListenerTest_WithInitialState,
       ReceiveSavedInvalidations) {
  EnableNotifications();
  listener_.Ready(fake_invalidation_client_);

  EXPECT_THAT(initial_state, test_util::Eq(GetSavedInvalidations()));

  ASSERT_EQ(2U, GetInvalidationCount(kBookmarksId_));
  EXPECT_EQ(100, GetVersion(kBookmarksId_));

  ASSERT_EQ(0U, GetInvalidationCount(kExtensionsId_));

  FireInvalidate(kExtensionsId_, 30, "thirty");

  ObjectIdSet ids = GetRegisteredIds();
  ids.insert(kExtensionsId_);
  listener_.UpdateRegisteredIds(ids);

  ASSERT_EQ(3U, GetInvalidationCount(kExtensionsId_));
  EXPECT_EQ(30, GetVersion(kExtensionsId_));
}

}  // namespace

}  // namespace syncer
