// Copyright 2017 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 <memory>
#include <utility>

#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/pref_notifier_impl.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/preferences/persistent_pref_store_impl.h"
#include "services/preferences/public/cpp/dictionary_value_update.h"
#include "services/preferences/public/cpp/persistent_pref_store_client.h"
#include "services/preferences/public/cpp/scoped_pref_update.h"
#include "services/preferences/public/interfaces/preferences.mojom.h"
#include "services/preferences/unittest_common.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace prefs {
namespace {

constexpr char kChildKey[] = "child";
constexpr char kOtherDictionaryKey[] = "other_key";

void DoNothingHandleReadError(PersistentPrefStore::PrefReadError error) {}

struct UpdateOrAck {
  std::vector<mojom::PrefUpdatePtr> updates;
  bool is_ack;
};

struct Request {
  std::string key;
  std::vector<std::string> path;
};

struct UpdateOrRequest {
  std::vector<mojom::PrefUpdatePtr> updates;
  Request request;
};

// A client connection to a between a PersistentPrefStoreImpl and a
// PersistentPrefStoreClient that provides control over when messages between
// the two are delivered.
class PrefServiceConnection : public mojom::PrefStoreObserver,
                              public mojom::PersistentPrefStore {
 public:
  explicit PrefServiceConnection(PersistentPrefStoreImpl* pref_store)
      : observer_binding_(this), pref_store_binding_(this) {
    auto connection = pref_store->CreateConnection({
        kKey, kOtherDictionaryKey, kDictionaryKey,
    });
    observer_binding_.Bind(
        std::move(connection->pref_store_connection->observer));
    connection->pref_store_connection->observer = mojo::MakeRequest(&observer_);

    pref_store_.Bind(std::move(connection->pref_store));
    pref_store_binding_.Bind(mojo::MakeRequest(&connection->pref_store));

    pref_store_client_ =
        base::MakeRefCounted<PersistentPrefStoreClient>(std::move(connection));
    auto pref_notifier = std::make_unique<PrefNotifierImpl>();
    auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
    pref_registry->RegisterIntegerPref(kKey, kInitialValue);
    pref_registry->RegisterIntegerPref(kOtherDictionaryKey, kInitialValue);
    pref_registry->RegisterDictionaryPref(kDictionaryKey);
    auto pref_value_store = std::make_unique<PrefValueStore>(
        nullptr, nullptr, nullptr, nullptr, pref_store_client_.get(), nullptr,
        pref_registry->defaults().get(), pref_notifier.get());
    pref_service_ = std::make_unique<PrefService>(
        std::move(pref_notifier), std::move(pref_value_store),
        pref_store_client_.get(), pref_registry.get(),
        base::Bind(&DoNothingHandleReadError), true);
  }

  ~PrefServiceConnection() override {
    observer_binding_.FlushForTesting();
    pref_store_binding_.FlushForTesting();
    EXPECT_TRUE(writes_.empty());
    EXPECT_TRUE(updates_.empty());
  }

  PrefService& pref_service() { return *pref_service_; }

  void WaitForWrites(size_t num_writes) {
    if (writes_.size() >= num_writes)
      return;

    expected_writes_ = num_writes;
    base::RunLoop run_loop;
    stop_ = run_loop.QuitClosure();
    run_loop.Run();
  }
  void ForwardWrites(size_t num_writes) {
    WaitForWrites(num_writes);
    for (size_t i = 0; i < num_writes; ++i) {
      auto& write = writes_.front();
      if (write.updates.empty()) {
        pref_store_->RequestValue(write.request.key, write.request.path);
      } else {
        pref_store_->SetValues(std::move(write.updates));
      }
      writes_.pop_front();
    }
    pref_store_.FlushForTesting();
  }
  void WaitForUpdates(size_t num_updates) {
    if (updates_.size() >= num_updates)
      return;

    expected_updates_ = num_updates;
    base::RunLoop run_loop;
    stop_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  void ForwardUpdates(size_t num_updates) {
    WaitForUpdates(num_updates);
    for (size_t i = 0; i < num_updates; ++i) {
      auto& update = updates_.front();
      if (update.is_ack) {
        observer_->OnPrefChangeAck();
      } else {
        observer_->OnPrefsChanged(std::move(update.updates));
      }
      updates_.pop_front();
    }
    observer_.FlushForTesting();
  }

  // mojom::PersistentPrefStore
  void SetValues(std::vector<mojom::PrefUpdatePtr> updates) override {
    writes_.push_back({std::move(updates)});
    if (writes_.size() == expected_writes_) {
      expected_writes_ = 0;
      std::move(stop_).Run();
    }
  }
  void RequestValue(const std::string& key,
                    const std::vector<std::string>& path) override {
    writes_.push_back({std::vector<mojom::PrefUpdatePtr>(), {key, path}});
    if (writes_.size() == expected_writes_) {
      expected_writes_ = 0;
      std::move(stop_).Run();
    }
  }
  void CommitPendingWrite(base::OnceClosure) override {}
  void SchedulePendingLossyWrites() override {}
  void ClearMutableValues() override {}
  void OnStoreDeletionFromDisk() override {}

  // mojom::PrefStoreObserver
  void OnPrefsChanged(std::vector<mojom::PrefUpdatePtr> updates) override {
    updates_.push_back({std::move(updates), false});
    if (updates_.size() == expected_updates_) {
      expected_updates_ = 0;
      std::move(stop_).Run();
    }
  }
  void OnInitializationCompleted(bool succeeded) override { NOTREACHED(); }
  void OnPrefChangeAck() override {
    updates_.push_back({std::vector<mojom::PrefUpdatePtr>(), true});
    acks_.push_back(updates_.size());
  }

 private:
  scoped_refptr<PersistentPrefStoreClient> pref_store_client_;
  std::unique_ptr<PrefService> pref_service_;
  mojom::PrefStoreObserverPtr observer_;
  mojom::PersistentPrefStorePtr pref_store_;
  mojo::Binding<mojom::PrefStoreObserver> observer_binding_;
  mojo::Binding<mojom::PersistentPrefStore> pref_store_binding_;

  base::OnceClosure stop_;
  size_t expected_writes_ = 0;
  size_t expected_updates_ = 0;

  base::circular_deque<UpdateOrRequest> writes_;
  base::circular_deque<UpdateOrAck> updates_;
  base::circular_deque<size_t> acks_;
};

class PersistentPrefStoreConsistencyTest : public testing::Test {
 public:
  void SetUp() override {
    pref_store_ = base::MakeRefCounted<InMemoryPrefStore>();
    pref_store_impl_ = std::make_unique<PersistentPrefStoreImpl>(
        pref_store_, base::BindOnce(&base::DoNothing));
  }

  PersistentPrefStore* pref_store() { return pref_store_.get(); }

  std::unique_ptr<PrefServiceConnection> CreateConnection() {
    return std::make_unique<PrefServiceConnection>(pref_store_impl_.get());
  }

 private:
  scoped_refptr<PersistentPrefStore> pref_store_;
  std::unique_ptr<PersistentPrefStoreImpl> pref_store_impl_;
  base::MessageLoop message_loop_;
};

TEST_F(PersistentPrefStoreConsistencyTest, TwoPrefs) {
  pref_store()->SetValue(kKey, std::make_unique<base::Value>(kInitialValue), 0);
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();

  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();

  EXPECT_EQ(kInitialValue, pref_service.GetInteger(kKey));
  EXPECT_EQ(kInitialValue, pref_service2.GetInteger(kKey));

  pref_service.SetInteger(kKey, 2);
  pref_service2.SetInteger(kKey, 3);

  // The writes arrive in the order: 2, 3.
  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  connection->ForwardUpdates(1);
  EXPECT_EQ(2, pref_service.GetInteger(kKey));

  // This connection already has a later value. It should not move backwards in
  // time.
  connection2->ForwardUpdates(1);
  EXPECT_EQ(3, pref_service2.GetInteger(kKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(3, pref_service.GetInteger(kKey));
  connection2->ForwardUpdates(1);
  EXPECT_EQ(3, pref_service2.GetInteger(kKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, TwoSubPrefs) {
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->SetInteger(kKey, 2);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 3);
  }

  // The writes arrive in the order: 2, 3.
  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue two_dict;
  two_dict.SetInteger(kKey, 2);
  base::DictionaryValue three_dict;
  three_dict.SetInteger(kKey, 3);

  connection->ForwardUpdates(1);
  EXPECT_EQ(two_dict, *pref_service.GetDictionary(kDictionaryKey));

  // This connection already has a later value. It should not move backwards in
  // time.
  connection2->ForwardUpdates(1);
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(three_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection2->ForwardUpdates(1);
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, DifferentSubPrefs) {
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->SetInteger(kKey, 2);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kOtherDictionaryKey, 3);
  }

  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue two_dict;
  two_dict.SetInteger(kKey, 2);
  base::DictionaryValue expected_dict;
  expected_dict.SetInteger(kKey, 2);
  expected_dict.SetInteger(kOtherDictionaryKey, 3);

  connection->ForwardUpdates(1);
  EXPECT_EQ(two_dict, *pref_service.GetDictionary(kDictionaryKey));

  // This connection already has a later value. It should not move backwards in
  // time.
  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, WriteParentThenChild) {
  auto initial_value = std::make_unique<base::DictionaryValue>();
  initial_value->SetDictionary(kDictionaryKey,
                               std::make_unique<base::DictionaryValue>());
  pref_store()->SetValue(kDictionaryKey, std::move(initial_value), 0);
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->SetInteger(kKey, 4);
    update->Clear();
    update->SetInteger(kKey, 2);
    update->SetInteger(kOtherDictionaryKey, 4);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 3);
  }

  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue two_and_four_dict;
  two_and_four_dict.SetInteger(kKey, 2);
  two_and_four_dict.SetInteger(kOtherDictionaryKey, 4);
  base::DictionaryValue three_dict;
  three_dict.SetInteger(kKey, 3);
  three_dict.SetDictionary(kDictionaryKey,
                           std::make_unique<base::DictionaryValue>());
  base::Value five_dict = three_dict.Clone();
  five_dict.SetKey(kKey, base::Value(5));
  base::DictionaryValue expected_dict;
  expected_dict.SetInteger(kKey, 3);
  expected_dict.SetInteger(kOtherDictionaryKey, 4);

  connection->ForwardUpdates(1);
  EXPECT_EQ(two_and_four_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));

  // Applying the other client's write would lose this client's write so is
  // ignored. Instead, this client requests an updated value from the service.
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));
  connection2->ForwardWrites(1);

  // Perform another update while waiting for the updated value from the
  // service.
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 5);
  }
  connection2->ForwardWrites(1);

  expected_dict.SetInteger(kKey, 5);
  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  // Ack for the original write.
  connection2->ForwardUpdates(1);
  EXPECT_EQ(five_dict, *pref_service2.GetDictionary(kDictionaryKey));

  // New value that is ignored due to the second in-flight write.
  connection2->ForwardUpdates(1);
  // Sending another request for the value from the service.
  connection2->ForwardWrites(1);
  EXPECT_EQ(five_dict, *pref_service2.GetDictionary(kDictionaryKey));

  // Ack for the second write.
  connection2->ForwardUpdates(1);
  EXPECT_EQ(five_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, WriteChildThenParent) {
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->SetInteger(kKey, 4);
    update->Clear();
    update->SetInteger(kKey, 2);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 3);
  }

  connection2->ForwardWrites(1);
  connection->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue expected_dict;
  expected_dict.SetInteger(kKey, 2);
  base::DictionaryValue three_dict;
  three_dict.SetInteger(kKey, 3);

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, WriteChildThenDeleteParent) {
  pref_store()->SetValue(kDictionaryKey,
                         std::make_unique<base::DictionaryValue>(), 0);
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  pref_service.ClearPref(kDictionaryKey);
  EXPECT_FALSE(pref_service.HasPrefPath(kDictionaryKey));
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 3);
  }

  connection2->ForwardWrites(1);
  connection->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue expected_dict;
  expected_dict.SetInteger(kKey, 2);
  base::DictionaryValue three_dict;
  three_dict.SetInteger(kKey, 3);

  connection->ForwardUpdates(1);
  EXPECT_FALSE(pref_service.HasPrefPath(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_FALSE(pref_service.HasPrefPath(kDictionaryKey));
  connection2->ForwardUpdates(1);
  EXPECT_FALSE(pref_service2.HasPrefPath(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, DeleteParentThenWriteChild) {
  auto initial_value = std::make_unique<base::DictionaryValue>();
  initial_value->SetInteger(kOtherDictionaryKey, 5);
  pref_store()->SetValue(kDictionaryKey, std::move(initial_value), 0);
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  pref_service.ClearPref(kDictionaryKey);
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 3);
  }

  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue intermediate_dict;
  intermediate_dict.SetInteger(kKey, 3);
  intermediate_dict.SetInteger(kOtherDictionaryKey, 5);

  base::DictionaryValue expected_dict;
  expected_dict.SetInteger(kKey, 3);

  connection->ForwardUpdates(1);
  EXPECT_FALSE(pref_service.HasPrefPath(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(intermediate_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardWrites(1);
  connection2->ForwardUpdates(1);
  EXPECT_EQ(intermediate_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, WriteParentThenDeleteChild) {
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->SetInteger(kKey, 1);
    update->Clear();
    update->SetInteger(kKey, 2);
    update->SetInteger(kOtherDictionaryKey, 4);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 3);
    update->RemovePath(kKey, nullptr);
  }

  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue two_and_four_dict;
  two_and_four_dict.SetInteger(kKey, 2);
  two_and_four_dict.SetInteger(kOtherDictionaryKey, 4);
  base::DictionaryValue empty_dict;
  base::DictionaryValue expected_dict;
  expected_dict.SetInteger(kOtherDictionaryKey, 4);

  connection->ForwardUpdates(1);
  EXPECT_EQ(two_and_four_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(empty_dict, *pref_service2.GetDictionary(kDictionaryKey));

  // Applying the other client's write would lose this client's write so is
  // ignored. Instead, this client requests an updated value from the service.
  EXPECT_EQ(empty_dict, *pref_service2.GetDictionary(kDictionaryKey));
  connection2->ForwardWrites(1);

  // Ack for the original write.
  connection2->ForwardUpdates(1);
  EXPECT_EQ(empty_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, DeleteChildThenWriteParent) {
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->SetInteger(kKey, 4);
    update->Clear();
    update->SetInteger(kKey, 2);
    update->SetInteger(kOtherDictionaryKey, 4);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 3);
    update->RemovePath(kKey, nullptr);
  }

  connection2->ForwardWrites(1);
  connection->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue empty_dict;
  base::DictionaryValue expected_dict;
  expected_dict.SetInteger(kKey, 2);
  expected_dict.SetInteger(kOtherDictionaryKey, 4);

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(empty_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, ReplaceParentThenWriteChild) {
  auto initial_value = std::make_unique<base::DictionaryValue>();
  initial_value->SetPath({kKey, kOtherDictionaryKey}, base::Value(5));
  pref_store()->SetValue(kDictionaryKey, std::move(initial_value), 0);
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->SetInteger(kKey, 1);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetPath({kKey, kChildKey}, base::Value(2));
  }

  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue simple_dict;
  simple_dict.SetInteger(kKey, 1);
  base::DictionaryValue nested_dict;
  nested_dict.SetPath({kKey, kChildKey}, base::Value(2));
  nested_dict.SetPath({kKey, kOtherDictionaryKey}, base::Value(5));
  base::DictionaryValue expected_dict;
  expected_dict.SetPath({kKey, kChildKey}, base::Value(2));

  connection->ForwardUpdates(1);
  EXPECT_EQ(simple_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(nested_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardWrites(1);
  connection2->ForwardUpdates(1);
  EXPECT_EQ(nested_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, WriteChildThenReplaceParent) {
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->SetInteger(kKey, 1);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetPath({kKey, kChildKey}, base::Value(2));
  }

  connection2->ForwardWrites(1);
  connection->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue simple_dict;
  simple_dict.SetInteger(kKey, 1);
  base::DictionaryValue nested_dict;
  nested_dict.SetPath({kKey, kChildKey}, base::Value(2));

  connection->ForwardUpdates(1);
  EXPECT_EQ(simple_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection->ForwardUpdates(1);
  EXPECT_EQ(simple_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(nested_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(simple_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, NestedWriteParentThenChild) {
  pref_store()->SetValue(kKey, std::make_unique<base::DictionaryValue>(), 0);
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    auto nested_dict =
        update->SetDictionary(kKey, std::make_unique<base::DictionaryValue>());
    nested_dict->SetInteger(kChildKey, 2);
    nested_dict->SetInteger(kOtherDictionaryKey, 4);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetPath({kKey, kChildKey}, base::Value(3));
  }

  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue two_and_four_dict;
  two_and_four_dict.SetPath({kKey, kChildKey}, base::Value(2));
  two_and_four_dict.SetPath({kKey, kOtherDictionaryKey}, base::Value(4));
  base::DictionaryValue three_dict;
  three_dict.SetPath({kKey, kChildKey}, base::Value(3));
  base::Value expected_dict = two_and_four_dict.Clone();
  expected_dict.SetPath({kKey, kChildKey}, base::Value(3));

  connection->ForwardUpdates(1);
  EXPECT_EQ(two_and_four_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));

  // Applying the other client's write would lose this client's write so is
  // ignored. Instead, this client requests an updated value from the service.
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));
  connection2->ForwardWrites(1);

  // Ack for the original write.
  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  // Updated value from the service.
  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest, NestedWriteChildThenParent) {
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    auto nested_dict =
        update->SetDictionary(kKey, std::make_unique<base::DictionaryValue>());
    nested_dict->SetInteger(kChildKey, 2);
    nested_dict->SetInteger(kOtherDictionaryKey, 4);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetPath({kKey, kChildKey}, base::Value(3));
  }

  connection2->ForwardWrites(1);
  connection->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue expected_dict;
  expected_dict.SetPath({kKey, kChildKey}, base::Value(2));
  expected_dict.SetPath({kKey, kOtherDictionaryKey}, base::Value(4));
  base::DictionaryValue three_dict;
  three_dict.SetPath({kKey, kChildKey}, base::Value(3));

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(three_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));
  connection2->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest,
       DeleteParentThenWriteChildThenDeleteParent) {
  auto initial_value = std::make_unique<base::DictionaryValue>();
  initial_value->SetInteger(kOtherDictionaryKey, 5);
  pref_store()->SetValue(kDictionaryKey, std::move(initial_value), 0);
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  pref_service.ClearPref(kDictionaryKey);
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetInteger(kKey, 3);
  }

  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue intermediate_dict;
  intermediate_dict.SetInteger(kKey, 3);
  intermediate_dict.SetInteger(kOtherDictionaryKey, 5);

  base::DictionaryValue expected_dict;
  expected_dict.SetInteger(kKey, 3);

  connection->ForwardUpdates(1);
  EXPECT_FALSE(pref_service.HasPrefPath(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(intermediate_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  pref_service.ClearPref(kDictionaryKey);
  connection->ForwardWrites(1);
  connection->ForwardUpdates(1);
  EXPECT_FALSE(pref_service.HasPrefPath(kDictionaryKey));

  connection2->ForwardWrites(1);
  connection2->ForwardUpdates(1);
  EXPECT_EQ(intermediate_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_FALSE(pref_service2.HasPrefPath(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_FALSE(pref_service2.HasPrefPath(kDictionaryKey));
}

TEST_F(PersistentPrefStoreConsistencyTest,
       NestedDeleteParentThenWriteChildThenDeleteChild) {
  auto initial_value = std::make_unique<base::DictionaryValue>();
  initial_value->SetPath({kKey, kOtherDictionaryKey}, base::Value(5));
  pref_store()->SetValue(kDictionaryKey, std::move(initial_value), 0);
  auto connection = CreateConnection();
  auto connection2 = CreateConnection();
  auto& pref_service = connection->pref_service();
  auto& pref_service2 = connection2->pref_service();
  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->RemovePath(kKey, nullptr);
  }
  {
    ScopedDictionaryPrefUpdate update(&pref_service2, kDictionaryKey);
    update->SetPath({kKey, kChildKey}, base::Value(3));
  }

  connection->ForwardWrites(1);
  connection2->ForwardWrites(1);

  connection->WaitForUpdates(2);
  connection2->WaitForUpdates(2);

  base::DictionaryValue intermediate_dict;
  intermediate_dict.SetPath({kKey, kChildKey}, base::Value(3));
  intermediate_dict.SetPath({kKey, kOtherDictionaryKey}, base::Value(5));

  base::DictionaryValue expected_dict;
  expected_dict.SetPath({kKey, kChildKey}, base::Value(3));

  base::DictionaryValue empty_dict;

  connection->ForwardUpdates(1);
  EXPECT_EQ(empty_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(intermediate_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection->ForwardUpdates(1);
  EXPECT_EQ(expected_dict, *pref_service.GetDictionary(kDictionaryKey));

  {
    ScopedDictionaryPrefUpdate update(&pref_service, kDictionaryKey);
    update->RemovePath(kKey, nullptr);
  }
  connection->ForwardWrites(1);
  connection->ForwardUpdates(1);
  EXPECT_TRUE(pref_service.HasPrefPath(kDictionaryKey));
  EXPECT_EQ(empty_dict, *pref_service.GetDictionary(kDictionaryKey));

  connection2->ForwardWrites(1);
  connection2->ForwardUpdates(1);
  EXPECT_EQ(intermediate_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(empty_dict, *pref_service2.GetDictionary(kDictionaryKey));

  connection2->ForwardUpdates(1);
  EXPECT_EQ(empty_dict, *pref_service2.GetDictionary(kDictionaryKey));
}

}  // namespace
}  // namespace prefs
