// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/prefs/json_pref_store.h"

#include <stdint.h>

#include <memory>
#include <utility>

#include "base/compiler_specific.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_samples.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/threading/thread.h"
#include "base/values.h"
#include "components/prefs/persistent_pref_store_unittest.h"
#include "components/prefs/pref_filter.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

const char kHomePage[] = "homepage";

const char kReadJson[] =
    "{\n"
    "  \"homepage\": \"http://www.cnn.com\",\n"
    "  \"some_directory\": \"/usr/local/\",\n"
    "  \"tabs\": {\n"
    "    \"new_windows_in_tabs\": true,\n"
    "    \"max_tabs\": 20\n"
    "  }\n"
    "}";

const char kInvalidJson[] = "!@#$%^&";

// Expected output for tests using RunBasicJsonPrefStoreTest().
const char kWriteGolden[] =
    "{\"homepage\":\"http://www.cnn.com\","
     "\"long_int\":{\"pref\":\"214748364842\"},"
     "\"some_directory\":\"/usr/sbin/\","
     "\"tabs\":{\"max_tabs\":10,\"new_windows_in_tabs\":false}}";

// A PrefFilter that will intercept all calls to FilterOnLoad() and hold on
// to the |prefs| until explicitly asked to release them.
class InterceptingPrefFilter : public PrefFilter {
 public:
  InterceptingPrefFilter();
  InterceptingPrefFilter(OnWriteCallbackPair callback_pair);

  InterceptingPrefFilter(const InterceptingPrefFilter&) = delete;
  InterceptingPrefFilter& operator=(const InterceptingPrefFilter&) = delete;

  ~InterceptingPrefFilter() override;

  // PrefFilter implementation:
  void FilterOnLoad(PostFilterOnLoadCallback post_filter_on_load_callback,
                    base::Value::Dict pref_store_contents) override;
  void FilterUpdate(std::string_view path) override {}
  OnWriteCallbackPair FilterSerializeData(
      base::Value::Dict& pref_store_contents) override {
    return std::move(on_write_callback_pair_);
  }
  void OnStoreDeletionFromDisk() override {}

  void SetPrefService(PrefService* pref_service) override {}

  bool has_intercepted_prefs() const { return intercepted_prefs_ != nullptr; }

  // Finalize an intercepted read, handing |intercepted_prefs_| back to its
  // JsonPrefStore.
  void ReleasePrefs();

 private:
  PostFilterOnLoadCallback post_filter_on_load_callback_;
  std::unique_ptr<base::Value::Dict> intercepted_prefs_;
  OnWriteCallbackPair on_write_callback_pair_;
};

InterceptingPrefFilter::InterceptingPrefFilter() = default;

InterceptingPrefFilter::InterceptingPrefFilter(
    OnWriteCallbackPair callback_pair) {
  on_write_callback_pair_ = std::move(callback_pair);
}

InterceptingPrefFilter::~InterceptingPrefFilter() = default;

void InterceptingPrefFilter::FilterOnLoad(
    PostFilterOnLoadCallback post_filter_on_load_callback,
    base::Value::Dict pref_store_contents) {
  post_filter_on_load_callback_ = std::move(post_filter_on_load_callback);
  intercepted_prefs_ =
      std::make_unique<base::Value::Dict>(std::move(pref_store_contents));
}

void InterceptingPrefFilter::ReleasePrefs() {
  EXPECT_FALSE(post_filter_on_load_callback_.is_null());
  std::unique_ptr<base::Value::Dict> prefs = std::move(intercepted_prefs_);
  std::move(post_filter_on_load_callback_).Run(std::move(*prefs), false);
}

class MockPrefStoreObserver : public PrefStore::Observer {
 public:
  MOCK_METHOD(void, OnInitializationCompleted, (bool), (override));
};

class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate {
 public:
  MOCK_METHOD(void, OnError, (PersistentPrefStore::PrefReadError), (override));
};

enum class CommitPendingWriteMode {
  // Basic mode.
  WITHOUT_CALLBACK,
  // With reply callback.
  WITH_CALLBACK,
  // With synchronous notify callback (synchronous after the write -- shouldn't
  // require pumping messages to observe).
  WITH_SYNCHRONOUS_CALLBACK,
};

base::test::TaskEnvironment::ThreadPoolExecutionMode GetExecutionMode(
    CommitPendingWriteMode commit_mode) {
  switch (commit_mode) {
    case CommitPendingWriteMode::WITHOUT_CALLBACK:
      [[fallthrough]];
    case CommitPendingWriteMode::WITH_CALLBACK:
      return base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED;
    case CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK:
      // Synchronous callbacks require async tasks to run on their own.
      return base::test::TaskEnvironment::ThreadPoolExecutionMode::ASYNC;
  }
}

void CommitPendingWrite(JsonPrefStore* pref_store,
                        CommitPendingWriteMode commit_pending_write_mode,
                        base::test::TaskEnvironment* task_environment) {
  switch (commit_pending_write_mode) {
    case CommitPendingWriteMode::WITHOUT_CALLBACK: {
      pref_store->CommitPendingWrite();
      task_environment->RunUntilIdle();
      break;
    }
    case CommitPendingWriteMode::WITH_CALLBACK: {
      TestCommitPendingWriteWithCallback(pref_store, task_environment);
      break;
    }
    case CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK: {
      base::WaitableEvent written;
      pref_store->CommitPendingWrite(
          base::OnceClosure(),
          base::BindOnce(&base::WaitableEvent::Signal, Unretained(&written)));
      written.Wait();
      break;
    }
  }
}

class JsonPrefStoreTest
    : public testing::TestWithParam<CommitPendingWriteMode> {
 public:
  JsonPrefStoreTest()
      : task_environment_(base::test::TaskEnvironment::MainThreadType::DEFAULT,
                          GetExecutionMode(GetParam())) {}

  JsonPrefStoreTest(const JsonPrefStoreTest&) = delete;
  JsonPrefStoreTest& operator=(const JsonPrefStoreTest&) = delete;

 protected:
  void SetUp() override {
    commit_pending_write_mode_ = GetParam();

    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  }

  // The path to temporary directory used to contain the test operations.
  base::ScopedTempDir temp_dir_;

  base::test::TaskEnvironment task_environment_;
  CommitPendingWriteMode commit_pending_write_mode_;
};

}  // namespace

// Test fallback behavior for a nonexistent file.
TEST_P(JsonPrefStoreTest, NonExistentFile) {
  base::FilePath bogus_input_file = temp_dir_.GetPath().AppendASCII("read.txt");
  ASSERT_FALSE(PathExists(bogus_input_file));
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(bogus_input_file);
  EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
            pref_store->ReadPrefs());
  EXPECT_FALSE(pref_store->ReadOnly());
  EXPECT_EQ(0u, pref_store->get_writer().previous_data_size());
}

// Test fallback behavior for an invalid file.
TEST_P(JsonPrefStoreTest, InvalidFile) {
  base::FilePath invalid_file = temp_dir_.GetPath().AppendASCII("invalid.json");
  ASSERT_TRUE(base::WriteFile(invalid_file, kInvalidJson));

  auto pref_store = base::MakeRefCounted<JsonPrefStore>(invalid_file);
  EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE,
            pref_store->ReadPrefs());
  EXPECT_FALSE(pref_store->ReadOnly());

  // The file should have been moved aside.
  EXPECT_FALSE(PathExists(invalid_file));
  base::FilePath moved_aside = temp_dir_.GetPath().AppendASCII("invalid.bad");
  EXPECT_TRUE(PathExists(moved_aside));

  std::string moved_aside_contents;
  ASSERT_TRUE(base::ReadFileToString(moved_aside, &moved_aside_contents));
  EXPECT_EQ(kInvalidJson, moved_aside_contents);
}

// This function is used to avoid code duplication while testing synchronous
// and asynchronous version of the JsonPrefStore loading. It validates that the
// given output file's contents matches kWriteGolden.
void RunBasicJsonPrefStoreTest(JsonPrefStore* pref_store,
                               const base::FilePath& output_file,
                               CommitPendingWriteMode commit_pending_write_mode,
                               base::test::TaskEnvironment* task_environment) {
  const char kNewWindowsInTabs[] = "tabs.new_windows_in_tabs";
  const char kMaxTabs[] = "tabs.max_tabs";
  const char kLongIntPref[] = "long_int.pref";

  std::string cnn("http://www.cnn.com");

  const Value* actual;
  EXPECT_TRUE(pref_store->GetValue(kHomePage, &actual));
  EXPECT_TRUE(actual->is_string());
  EXPECT_EQ(cnn, actual->GetString());

  const char kSomeDirectory[] = "some_directory";

  EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
  EXPECT_TRUE(actual->is_string());
  EXPECT_EQ("/usr/local/", actual->GetString());
  base::FilePath some_path(FILE_PATH_LITERAL("/usr/sbin/"));

  pref_store->SetValue(kSomeDirectory, Value(some_path.AsUTF8Unsafe()),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
  EXPECT_TRUE(actual->is_string());
  EXPECT_EQ(some_path.AsUTF8Unsafe(), actual->GetString());

  // Test reading some other data types from sub-dictionaries.
  EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
  EXPECT_TRUE(actual->is_bool());
  EXPECT_TRUE(actual->GetBool());

  pref_store->SetValue(kNewWindowsInTabs, Value(false),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
  EXPECT_TRUE(actual->is_bool());
  EXPECT_FALSE(actual->GetBool());

  EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
  ASSERT_TRUE(actual->is_int());
  EXPECT_EQ(20, actual->GetInt());
  pref_store->SetValue(kMaxTabs, Value(10),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
  ASSERT_TRUE(actual->is_int());
  EXPECT_EQ(10, actual->GetInt());

  pref_store->SetValue(kLongIntPref,
                       Value(base::NumberToString(214748364842LL)),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  EXPECT_TRUE(pref_store->GetValue(kLongIntPref, &actual));
  EXPECT_TRUE(actual->is_string());
  int64_t value;
  base::StringToInt64(actual->GetString(), &value);
  EXPECT_EQ(214748364842LL, value);

  // Serialize and compare to expected output.
  CommitPendingWrite(pref_store, commit_pending_write_mode, task_environment);

  std::string output_contents;
  ASSERT_TRUE(base::ReadFileToString(output_file, &output_contents));
  EXPECT_EQ(kWriteGolden, output_contents);
  ASSERT_TRUE(base::DeleteFile(output_file));
}

TEST_P(JsonPrefStoreTest, Basic) {
  base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
  ASSERT_TRUE(base::WriteFile(input_file, kReadJson));

  // Test that the persistent value can be loaded.
  ASSERT_TRUE(PathExists(input_file));
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(input_file);
  ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
  EXPECT_FALSE(pref_store->ReadOnly());
  EXPECT_TRUE(pref_store->IsInitializationComplete());
  EXPECT_GT(pref_store->get_writer().previous_data_size(), 0u);

  // The JSON file looks like this:
  // {
  //   "homepage": "http://www.cnn.com",
  //   "some_directory": "/usr/local/",
  //   "tabs": {
  //     "new_windows_in_tabs": true,
  //     "max_tabs": 20
  //   }
  // }

  RunBasicJsonPrefStoreTest(pref_store.get(), input_file,
                            commit_pending_write_mode_, &task_environment_);
}

TEST_P(JsonPrefStoreTest, BasicAsync) {
  base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
  ASSERT_TRUE(base::WriteFile(input_file, kReadJson));

  // Test that the persistent value can be loaded.
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(input_file);

  {
    MockPrefStoreObserver mock_observer;
    pref_store->AddObserver(&mock_observer);

    MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
    pref_store->ReadPrefsAsync(mock_error_delegate);

    EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
    EXPECT_CALL(*mock_error_delegate,
                OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
    task_environment_.RunUntilIdle();
    pref_store->RemoveObserver(&mock_observer);

    EXPECT_FALSE(pref_store->ReadOnly());
    EXPECT_TRUE(pref_store->IsInitializationComplete());
    EXPECT_GT(pref_store->get_writer().previous_data_size(), 0u);
  }

  // The JSON file looks like this:
  // {
  //   "homepage": "http://www.cnn.com",
  //   "some_directory": "/usr/local/",
  //   "tabs": {
  //     "new_windows_in_tabs": true,
  //     "max_tabs": 20
  //   }
  // }

  RunBasicJsonPrefStoreTest(pref_store.get(), input_file,
                            commit_pending_write_mode_, &task_environment_);
}

TEST_P(JsonPrefStoreTest, PreserveEmptyValues) {
  FilePath pref_file = temp_dir_.GetPath().AppendASCII("empty_values.json");

  auto pref_store = base::MakeRefCounted<JsonPrefStore>(pref_file);

  // Set some keys with empty values.
  pref_store->SetValue("list", base::Value(base::Value::List()),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  pref_store->SetValue("dict", base::Value(base::Value::Dict()),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);

  // Write to file.
  CommitPendingWrite(pref_store.get(), commit_pending_write_mode_,
                     &task_environment_);

  // Reload.
  pref_store = base::MakeRefCounted<JsonPrefStore>(pref_file);
  ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
  ASSERT_FALSE(pref_store->ReadOnly());

  // Check values.
  const Value* result = nullptr;
  EXPECT_TRUE(pref_store->GetValue("list", &result));
  EXPECT_EQ(Value::List(), *result);
  EXPECT_TRUE(pref_store->GetValue("dict", &result));
  EXPECT_EQ(Value::Dict(), *result);
}

// This test is just documenting some potentially non-obvious behavior. It
// shouldn't be taken as normative.
TEST_P(JsonPrefStoreTest, RemoveClearsEmptyParent) {
  FilePath pref_file = temp_dir_.GetPath().AppendASCII("empty_values.json");

  auto pref_store = base::MakeRefCounted<JsonPrefStore>(pref_file);

  base::Value::Dict dict;
  dict.Set("key", "value");
  pref_store->SetValue("dict", base::Value(std::move(dict)),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);

  pref_store->RemoveValue("dict.key",
                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);

  const base::Value* retrieved_dict = nullptr;
  bool has_dict = pref_store->GetValue("dict", &retrieved_dict);
  EXPECT_FALSE(has_dict);
}

// Tests asynchronous reading of the file when there is no file.
TEST_P(JsonPrefStoreTest, AsyncNonExistingFile) {
  base::FilePath bogus_input_file = temp_dir_.GetPath().AppendASCII("read.txt");
  ASSERT_FALSE(PathExists(bogus_input_file));
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(bogus_input_file);
  MockPrefStoreObserver mock_observer;
  pref_store->AddObserver(&mock_observer);

  MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate;
  pref_store->ReadPrefsAsync(mock_error_delegate);

  EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
  EXPECT_CALL(*mock_error_delegate,
              OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1);
  task_environment_.RunUntilIdle();
  pref_store->RemoveObserver(&mock_observer);

  EXPECT_FALSE(pref_store->ReadOnly());
}

TEST_P(JsonPrefStoreTest, ReadWithInterceptor) {
  base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
  ASSERT_TRUE(base::WriteFile(input_file, kReadJson));

  std::unique_ptr<InterceptingPrefFilter> intercepting_pref_filter(
      new InterceptingPrefFilter());
  InterceptingPrefFilter* raw_intercepting_pref_filter_ =
      intercepting_pref_filter.get();
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(
      input_file, std::move(intercepting_pref_filter));

  ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
            pref_store->ReadPrefs());
  EXPECT_FALSE(pref_store->ReadOnly());

  // The store shouldn't be considered initialized until the interceptor
  // returns.
  EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
  EXPECT_FALSE(pref_store->IsInitializationComplete());
  EXPECT_FALSE(pref_store->GetValue(kHomePage, nullptr));

  raw_intercepting_pref_filter_->ReleasePrefs();

  EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
  EXPECT_TRUE(pref_store->IsInitializationComplete());
  EXPECT_TRUE(pref_store->GetValue(kHomePage, nullptr));

  // The JSON file looks like this:
  // {
  //   "homepage": "http://www.cnn.com",
  //   "some_directory": "/usr/local/",
  //   "tabs": {
  //     "new_windows_in_tabs": true,
  //     "max_tabs": 20
  //   }
  // }

  RunBasicJsonPrefStoreTest(pref_store.get(), input_file,
                            commit_pending_write_mode_, &task_environment_);
}

TEST_P(JsonPrefStoreTest, ReadAsyncWithInterceptor) {
  base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
  ASSERT_TRUE(base::WriteFile(input_file, kReadJson));

  std::unique_ptr<InterceptingPrefFilter> intercepting_pref_filter(
      new InterceptingPrefFilter());
  InterceptingPrefFilter* raw_intercepting_pref_filter_ =
      intercepting_pref_filter.get();
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(
      input_file, std::move(intercepting_pref_filter));

  MockPrefStoreObserver mock_observer;
  pref_store->AddObserver(&mock_observer);

  // Ownership of the |mock_error_delegate| is handed to the |pref_store| below.
  MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;

  {
    pref_store->ReadPrefsAsync(mock_error_delegate);

    EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(0);
    // EXPECT_CALL(*mock_error_delegate,
    //             OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
    task_environment_.RunUntilIdle();

    EXPECT_FALSE(pref_store->ReadOnly());
    EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
    EXPECT_FALSE(pref_store->IsInitializationComplete());
    EXPECT_FALSE(pref_store->GetValue(kHomePage, nullptr));
  }

  {
    EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
    // EXPECT_CALL(*mock_error_delegate,
    //             OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);

    raw_intercepting_pref_filter_->ReleasePrefs();

    EXPECT_FALSE(pref_store->ReadOnly());
    EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
    EXPECT_TRUE(pref_store->IsInitializationComplete());
    EXPECT_TRUE(pref_store->GetValue(kHomePage, nullptr));
  }

  pref_store->RemoveObserver(&mock_observer);

  // The JSON file looks like this:
  // {
  //   "homepage": "http://www.cnn.com",
  //   "some_directory": "/usr/local/",
  //   "tabs": {
  //     "new_windows_in_tabs": true,
  //     "max_tabs": 20
  //   }
  // }

  RunBasicJsonPrefStoreTest(pref_store.get(), input_file,
                            commit_pending_write_mode_, &task_environment_);
}

TEST_P(JsonPrefStoreTest, RemoveValuesByPrefix) {
  FilePath pref_file = temp_dir_.GetPath().AppendASCII("empty.json");

  auto pref_store = base::MakeRefCounted<JsonPrefStore>(pref_file);

  const Value* value;
  const std::string prefix = "pref";
  const std::string subpref_name1 = "pref.a";
  const std::string subpref_name2 = "pref.b";
  const std::string other_name = "other";

  pref_store->SetValue(subpref_name1, base::Value(42),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  pref_store->SetValue(subpref_name2, base::Value(42),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  pref_store->SetValue(other_name, base::Value(42),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);

  pref_store->RemoveValuesByPrefixSilently(prefix);
  EXPECT_FALSE(pref_store->GetValue(subpref_name1, &value));
  EXPECT_FALSE(pref_store->GetValue(subpref_name2, &value));
  EXPECT_TRUE(pref_store->GetValue(other_name, &value));
}

TEST_P(JsonPrefStoreTest, HasReadErrorDelegate) {
  base::FilePath bogus_input_file = temp_dir_.GetPath().AppendASCII("read.txt");
  ASSERT_FALSE(PathExists(bogus_input_file));
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(bogus_input_file);

  EXPECT_FALSE(pref_store->HasReadErrorDelegate());

  pref_store->ReadPrefsAsync(new MockReadErrorDelegate);
  EXPECT_TRUE(pref_store->HasReadErrorDelegate());
}

TEST_P(JsonPrefStoreTest, HasReadErrorDelegateWithNullDelegate) {
  base::FilePath bogus_input_file = temp_dir_.GetPath().AppendASCII("read.txt");
  ASSERT_FALSE(PathExists(bogus_input_file));
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(bogus_input_file);

  EXPECT_FALSE(pref_store->HasReadErrorDelegate());

  pref_store->ReadPrefsAsync(nullptr);
  // Returns true even though no instance was passed.
  EXPECT_TRUE(pref_store->HasReadErrorDelegate());
}

INSTANTIATE_TEST_SUITE_P(
    JsonPrefStoreTestVariations,
    JsonPrefStoreTest,
    ::testing::Values(CommitPendingWriteMode::WITHOUT_CALLBACK,
                      CommitPendingWriteMode::WITH_CALLBACK,
                      CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK));

class JsonPrefStoreLossyWriteTest : public JsonPrefStoreTest {
 public:
  JsonPrefStoreLossyWriteTest() = default;

  JsonPrefStoreLossyWriteTest(const JsonPrefStoreLossyWriteTest&) = delete;
  JsonPrefStoreLossyWriteTest& operator=(const JsonPrefStoreLossyWriteTest&) =
      delete;

 protected:
  void SetUp() override {
    JsonPrefStoreTest::SetUp();
    test_file_ = temp_dir_.GetPath().AppendASCII("test.json");
  }

  scoped_refptr<JsonPrefStore> CreatePrefStore() {
    return base::MakeRefCounted<JsonPrefStore>(test_file_);
  }

  // Return the ImportantFileWriter for a given JsonPrefStore.
  ImportantFileWriter* GetImportantFileWriter(JsonPrefStore* pref_store) {
    return &(pref_store->writer_);
  }

  // Get the contents of kTestFile. Pumps the message loop before returning the
  // result.
  std::string GetTestFileContents() {
    task_environment_.RunUntilIdle();
    std::string file_contents;
    ReadFileToString(test_file_, &file_contents);
    return file_contents;
  }

 private:
  base::FilePath test_file_;
};

TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteBasic) {
  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());

  // Set a normal pref and check that it gets scheduled to be written.
  ASSERT_FALSE(file_writer->HasPendingWrite());
  pref_store->SetValue("normal", base::Value("normal"),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  ASSERT_TRUE(file_writer->HasPendingWrite());
  file_writer->DoScheduledWrite();
  ASSERT_EQ("{\"normal\":\"normal\"}", GetTestFileContents());
  ASSERT_FALSE(file_writer->HasPendingWrite());

  // Set a lossy pref and check that it is not scheduled to be written.
  // SetValue/RemoveValue.
  pref_store->SetValue("lossy", base::Value("lossy"),
                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_FALSE(file_writer->HasPendingWrite());
  pref_store->RemoveValue("lossy", WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_FALSE(file_writer->HasPendingWrite());

  // SetValueSilently/RemoveValueSilently.
  pref_store->SetValueSilently("lossy", base::Value("lossy"),
                               WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_FALSE(file_writer->HasPendingWrite());
  pref_store->RemoveValueSilently("lossy",
                                  WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_FALSE(file_writer->HasPendingWrite());

  // ReportValueChanged.
  pref_store->SetValue("lossy", base::Value("lossy"),
                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_FALSE(file_writer->HasPendingWrite());
  pref_store->ReportValueChanged("lossy",
                                 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_FALSE(file_writer->HasPendingWrite());

  // Call CommitPendingWrite and check that the lossy pref and the normal pref
  // are there with the last values set above.
  pref_store->CommitPendingWrite(base::OnceClosure());
  ASSERT_FALSE(file_writer->HasPendingWrite());
  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
            GetTestFileContents());
}

TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossyFirst) {
  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());

  // Set a lossy pref and check that it is not scheduled to be written.
  ASSERT_FALSE(file_writer->HasPendingWrite());
  pref_store->SetValue("lossy", base::Value("lossy"),
                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_FALSE(file_writer->HasPendingWrite());

  // Set a normal pref and check that it is scheduled to be written.
  pref_store->SetValue("normal", base::Value("normal"),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  ASSERT_TRUE(file_writer->HasPendingWrite());

  // Call DoScheduledWrite and check both prefs get written.
  file_writer->DoScheduledWrite();
  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
            GetTestFileContents());
  ASSERT_FALSE(file_writer->HasPendingWrite());
}

TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossySecond) {
  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());

  // Set a normal pref and check that it is scheduled to be written.
  ASSERT_FALSE(file_writer->HasPendingWrite());
  pref_store->SetValue("normal", base::Value("normal"),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  ASSERT_TRUE(file_writer->HasPendingWrite());

  // Set a lossy pref and check that the write is still scheduled.
  pref_store->SetValue("lossy", base::Value("lossy"),
                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_TRUE(file_writer->HasPendingWrite());

  // Call DoScheduledWrite and check both prefs get written.
  file_writer->DoScheduledWrite();
  ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
            GetTestFileContents());
  ASSERT_FALSE(file_writer->HasPendingWrite());
}

TEST_P(JsonPrefStoreLossyWriteTest, ScheduleLossyWrite) {
  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());

  // Set a lossy pref and check that it is not scheduled to be written.
  pref_store->SetValue("lossy", base::Value("lossy"),
                       WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
  ASSERT_FALSE(file_writer->HasPendingWrite());

  // Schedule pending lossy writes and check that it is scheduled.
  pref_store->SchedulePendingLossyWrites();
  ASSERT_TRUE(file_writer->HasPendingWrite());

  // Call CommitPendingWrite and check that the lossy pref is there with the
  // last value set above.
  pref_store->CommitPendingWrite(base::OnceClosure());
  ASSERT_FALSE(file_writer->HasPendingWrite());
  ASSERT_EQ("{\"lossy\":\"lossy\"}", GetTestFileContents());
}

INSTANTIATE_TEST_SUITE_P(
    JsonPrefStoreLossyWriteTestVariations,
    JsonPrefStoreLossyWriteTest,
    ::testing::Values(CommitPendingWriteMode::WITHOUT_CALLBACK,
                      CommitPendingWriteMode::WITH_CALLBACK,
                      CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK));

class SuccessfulWriteReplyObserver {
 public:
  SuccessfulWriteReplyObserver() = default;

  SuccessfulWriteReplyObserver(const SuccessfulWriteReplyObserver&) = delete;
  SuccessfulWriteReplyObserver& operator=(const SuccessfulWriteReplyObserver&) =
      delete;

  // Returns true if a successful write was observed via on_successful_write()
  // and resets the observation state to false regardless.
  bool GetAndResetObservationState() {
    bool was_successful_write_observed = successful_write_reply_observed_;
    successful_write_reply_observed_ = false;
    return was_successful_write_observed;
  }

  // Register OnWrite() to be called on the next write of |json_pref_store|.
  void ObserveNextWriteCallback(JsonPrefStore* json_pref_store);

  void OnSuccessfulWrite() {
    EXPECT_FALSE(successful_write_reply_observed_);
    successful_write_reply_observed_ = true;
  }

 private:
  bool successful_write_reply_observed_ = false;
};

void SuccessfulWriteReplyObserver::ObserveNextWriteCallback(
    JsonPrefStore* json_pref_store) {
  json_pref_store->RegisterOnNextSuccessfulWriteReply(
      base::BindOnce(&SuccessfulWriteReplyObserver::OnSuccessfulWrite,
                     base::Unretained(this)));
}

enum WriteCallbackObservationState {
  NOT_CALLED,
  CALLED_WITH_ERROR,
  CALLED_WITH_SUCCESS,
};

class WriteCallbacksObserver {
 public:
  WriteCallbacksObserver() = default;

  WriteCallbacksObserver(const WriteCallbacksObserver&) = delete;
  WriteCallbacksObserver& operator=(const WriteCallbacksObserver&) = delete;

  // Register OnWrite() to be called on the next write of |json_pref_store|.
  void ObserveNextWriteCallback(JsonPrefStore* json_pref_store);

  // Returns whether OnPreWrite() was called, and resets the observation state
  // to false.
  bool GetAndResetPreWriteObservationState();

  // Returns the |WriteCallbackObservationState| which was observed, then resets
  // it to |NOT_CALLED|.
  WriteCallbackObservationState GetAndResetPostWriteObservationState();

  JsonPrefStore::OnWriteCallbackPair GetCallbackPair() {
    return std::make_pair(base::BindOnce(&WriteCallbacksObserver::OnPreWrite,
                                         base::Unretained(this)),
                          base::BindOnce(&WriteCallbacksObserver::OnPostWrite,
                                         base::Unretained(this)));
  }

  void OnPreWrite() {
    EXPECT_FALSE(pre_write_called_);
    pre_write_called_ = true;
  }

  void OnPostWrite(bool success) {
    EXPECT_EQ(NOT_CALLED, post_write_observation_state_);
    post_write_observation_state_ =
        success ? CALLED_WITH_SUCCESS : CALLED_WITH_ERROR;
  }

 private:
  bool pre_write_called_ = false;
  WriteCallbackObservationState post_write_observation_state_ = NOT_CALLED;
};

void WriteCallbacksObserver::ObserveNextWriteCallback(JsonPrefStore* writer) {
  writer->RegisterOnNextWriteSynchronousCallbacks(GetCallbackPair());
}

bool WriteCallbacksObserver::GetAndResetPreWriteObservationState() {
  bool observation_state = pre_write_called_;
  pre_write_called_ = false;
  return observation_state;
}

WriteCallbackObservationState
WriteCallbacksObserver::GetAndResetPostWriteObservationState() {
  WriteCallbackObservationState state = post_write_observation_state_;
  pre_write_called_ = false;
  post_write_observation_state_ = NOT_CALLED;
  return state;
}

class JsonPrefStoreCallbackTest : public testing::Test {
 public:
  JsonPrefStoreCallbackTest() = default;

  JsonPrefStoreCallbackTest(const JsonPrefStoreCallbackTest&) = delete;
  JsonPrefStoreCallbackTest& operator=(const JsonPrefStoreCallbackTest&) =
      delete;

 protected:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    test_file_ = temp_dir_.GetPath().AppendASCII("test.json");
  }

  scoped_refptr<JsonPrefStore> CreatePrefStore() {
    return base::MakeRefCounted<JsonPrefStore>(test_file_);
  }

  // Return the ImportantFileWriter for a given JsonPrefStore.
  ImportantFileWriter* GetImportantFileWriter(JsonPrefStore* pref_store) {
    return &(pref_store->writer_);
  }

  void TriggerFakeWriteForCallback(JsonPrefStore* pref_store, bool success) {
    JsonPrefStore::PostWriteCallback(
        base::BindOnce(&JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback,
                       pref_store->AsWeakPtr()),
        base::BindOnce(&WriteCallbacksObserver::OnPostWrite,
                       base::Unretained(&write_callback_observer_)),
        base::SequencedTaskRunner::GetCurrentDefault(), success);
  }

  SuccessfulWriteReplyObserver successful_write_reply_observer_;
  WriteCallbacksObserver write_callback_observer_;

 protected:
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::MainThreadType::DEFAULT,
      base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED};

  base::ScopedTempDir temp_dir_;

 private:
  base::FilePath test_file_;
};

TEST_F(JsonPrefStoreCallbackTest, TestSerializeDataCallbacks) {
  base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
  ASSERT_TRUE(base::WriteFile(input_file, kReadJson));

  std::unique_ptr<InterceptingPrefFilter> intercepting_pref_filter(
      new InterceptingPrefFilter(write_callback_observer_.GetCallbackPair()));
  auto pref_store = base::MakeRefCounted<JsonPrefStore>(
      input_file, std::move(intercepting_pref_filter));
  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());

  EXPECT_EQ(NOT_CALLED,
            write_callback_observer_.GetAndResetPostWriteObservationState());
  pref_store->SetValue("normal", base::Value("normal"),
                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  file_writer->DoScheduledWrite();

  // The observer should not be invoked right away.
  EXPECT_FALSE(write_callback_observer_.GetAndResetPreWriteObservationState());
  EXPECT_EQ(NOT_CALLED,
            write_callback_observer_.GetAndResetPostWriteObservationState());

  task_environment_.RunUntilIdle();

  EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
  EXPECT_EQ(CALLED_WITH_SUCCESS,
            write_callback_observer_.GetAndResetPostWriteObservationState());
}

TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacks) {
  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());

  // Test RegisterOnNextWriteSynchronousCallbacks after
  // RegisterOnNextSuccessfulWriteReply.
  successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
  write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
  file_writer->WriteNow("foo");
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
  EXPECT_EQ(CALLED_WITH_SUCCESS,
            write_callback_observer_.GetAndResetPostWriteObservationState());

  // Test RegisterOnNextSuccessfulWriteReply after
  // RegisterOnNextWriteSynchronousCallbacks.
  successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
  write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
  file_writer->WriteNow("foo");
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
  EXPECT_EQ(CALLED_WITH_SUCCESS,
            write_callback_observer_.GetAndResetPostWriteObservationState());

  // Test RegisterOnNextSuccessfulWriteReply only.
  successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
  file_writer->WriteNow("foo");
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_FALSE(write_callback_observer_.GetAndResetPreWriteObservationState());
  EXPECT_EQ(NOT_CALLED,
            write_callback_observer_.GetAndResetPostWriteObservationState());

  // Test RegisterOnNextWriteSynchronousCallbacks only.
  write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
  file_writer->WriteNow("foo");
  task_environment_.RunUntilIdle();
  EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
  EXPECT_EQ(CALLED_WITH_SUCCESS,
            write_callback_observer_.GetAndResetPostWriteObservationState());
}

TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacksWithFakeFailure) {
  scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();

  // Confirm that the observers are invoked.
  successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
  TriggerFakeWriteForCallback(pref_store.get(), true);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_EQ(CALLED_WITH_SUCCESS,
            write_callback_observer_.GetAndResetPostWriteObservationState());

  // Confirm that the observation states were reset.
  EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_EQ(NOT_CALLED,
            write_callback_observer_.GetAndResetPostWriteObservationState());

  // Confirm that re-installing the observers works for another write.
  successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
  TriggerFakeWriteForCallback(pref_store.get(), true);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_EQ(CALLED_WITH_SUCCESS,
            write_callback_observer_.GetAndResetPostWriteObservationState());

  // Confirm that the successful observer is not invoked by an unsuccessful
  // write, and that the synchronous observer is invoked.
  successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
  TriggerFakeWriteForCallback(pref_store.get(), false);
  task_environment_.RunUntilIdle();
  EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_EQ(CALLED_WITH_ERROR,
            write_callback_observer_.GetAndResetPostWriteObservationState());

  // Do a real write, and confirm that the successful observer was invoked after
  // being set by |PostWriteCallback| by the last TriggerFakeWriteCallback.
  ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
  file_writer->WriteNow("foo");
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_EQ(NOT_CALLED,
            write_callback_observer_.GetAndResetPostWriteObservationState());
}

TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacksDuringProfileDeath) {
  // Create a JsonPrefStore and attach observers to it, then delete it by making
  // it go out of scope to simulate profile switch or Chrome shutdown.
  {
    scoped_refptr<JsonPrefStore> soon_out_of_scope_pref_store =
        CreatePrefStore();
    ImportantFileWriter* file_writer =
        GetImportantFileWriter(soon_out_of_scope_pref_store.get());
    successful_write_reply_observer_.ObserveNextWriteCallback(
        soon_out_of_scope_pref_store.get());
    write_callback_observer_.ObserveNextWriteCallback(
        soon_out_of_scope_pref_store.get());
    file_writer->WriteNow("foo");
  }
  task_environment_.RunUntilIdle();
  EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
  EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
  EXPECT_EQ(CALLED_WITH_SUCCESS,
            write_callback_observer_.GetAndResetPostWriteObservationState());
}

class MockApiTestPrefFilter : public PrefFilter {
 public:
  MockApiTestPrefFilter() = default;
  ~MockApiTestPrefFilter() override = default;

  void FilterOnLoad(PostFilterOnLoadCallback on_done,
                    base::Value::Dict pref_store_contents) override {
    std::move(on_done).Run(std::move(pref_store_contents), false);
  }

  OnWriteCallbackPair FilterSerializeData(
      base::Value::Dict& pref_store_contents) override {
    return OnWriteCallbackPair();
  }

  void FilterUpdate(std::string_view path) override {}
  void OnStoreDeletionFromDisk() override {}

  void SetPrefService(PrefService* pref_service) override {
    pref_service_ = pref_service;
  }

  PrefService* get_pref_service_for_testing() const {
    return pref_service_.get();
  }

 private:
  raw_ptr<PrefService> pref_service_ = nullptr;
};

// A test fixture for testing the new APIs on JsonPrefStore.
class JsonPrefStoreApiTest : public testing::Test {
 protected:
  JsonPrefStoreApiTest()
      : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}

  void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }

  base::FilePath GetTestFile() {
    return temp_dir_.GetPath().AppendASCII("test_api.json");
  }

  base::test::TaskEnvironment task_environment_;
  base::ScopedTempDir temp_dir_;
};

TEST_F(JsonPrefStoreApiTest, GetFilter) {
  // Test with a filter.
  auto filter = std::make_unique<MockApiTestPrefFilter>();
  PrefFilter* raw_filter = filter.get();
  auto pref_store_with_filter =
      base::MakeRefCounted<JsonPrefStore>(GetTestFile(), std::move(filter));
  EXPECT_EQ(raw_filter, pref_store_with_filter->GetFilter());

  // Test without a filter.
  auto pref_store_without_filter =
      base::MakeRefCounted<JsonPrefStore>(GetTestFile());
  EXPECT_EQ(nullptr, pref_store_without_filter->GetFilter());
}

TEST_F(JsonPrefStoreApiTest, SetPrefServiceOnFilter) {
  auto filter = std::make_unique<MockApiTestPrefFilter>();
  MockApiTestPrefFilter* raw_filter = filter.get();
  auto pref_store =
      base::MakeRefCounted<JsonPrefStore>(GetTestFile(), std::move(filter));

  // Initially, the filter should not have a PrefService.
  // This emulates the scenario where the filter object is created but the pref
  // service isn't available yet.
  EXPECT_EQ(nullptr, raw_filter->get_pref_service_for_testing());

  TestingPrefServiceSimple pref_service;

  // Set the PrefService on the filter via the store's API.
  PrefFilter* retrieved_filter = pref_store->GetFilter();
  ASSERT_NE(nullptr, retrieved_filter);
  retrieved_filter->SetPrefService(&pref_service);

  // Verify that the filter now holds the correct PrefService pointer.
  EXPECT_EQ(&pref_service, raw_filter->get_pref_service_for_testing());
}
}  // namespace base
