// 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 "components/leveldb_proto/unique_proto_database.h"

#include <stddef.h>

#include <map>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/leveldb_proto/leveldb_database.h"
#include "components/leveldb_proto/testing/proto/test_db.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/leveldb_chrome.h"

using base::ScopedTempDir;
using base::test::ScopedTaskEnvironment;
using leveldb_env::Options;
using testing::_;
using testing::Invoke;
using testing::MakeMatcher;
using testing::Matcher;
using testing::MatcherInterface;
using testing::MatchResultListener;
using testing::Return;
using testing::UnorderedElementsAre;

namespace leveldb_proto {

namespace {

typedef std::map<std::string, TestProto> EntryMap;

const char kTestLevelDBClientName[] = "Test";

class MockDB : public LevelDB {
 public:
  MOCK_METHOD3(Init,
               leveldb::Status(const base::FilePath& database_dir,
                               const leveldb_env::Options& options,
                               bool));
  MOCK_METHOD3(Save,
               bool(const KeyValueVector&, const KeyVector&, leveldb::Status*));
  MOCK_METHOD3(UpdateWithRemoveFilter,
               bool(const base::StringPairs&,
                    const KeyFilter&,
                    leveldb::Status*));
  MOCK_METHOD4(UpdateWithRemoveFilter,
               bool(const base::StringPairs&,
                    const KeyFilter&,
                    const std::string&,
                    leveldb::Status*));
  MOCK_METHOD1(Load, bool(std::vector<std::string>*));
  MOCK_METHOD2(LoadWithFilter,
               bool(const KeyFilter&, std::vector<std::string>*));
  MOCK_METHOD4(LoadWithFilter,
               bool(const KeyFilter&,
                    std::vector<std::string>*,
                    const leveldb::ReadOptions&,
                    const std::string&));
  MOCK_METHOD1(LoadKeysAndEntries, bool(std::map<std::string, std::string>*));
  MOCK_METHOD2(LoadKeysAndEntriesWithFilter,
               bool(const KeyFilter&, std::map<std::string, std::string>*));
  MOCK_METHOD4(LoadKeysAndEntriesWithFilter,
               bool(const KeyFilter&,
                    std::map<std::string, std::string>*,
                    const leveldb::ReadOptions&,
                    const std::string&));
  MOCK_METHOD5(LoadKeysAndEntriesWhile,
               bool(const KeyFilter&,
                    std::map<std::string, std::string>*,
                    const leveldb::ReadOptions&,
                    const std::string&,
                    const KeyFilter&));

  MOCK_METHOD4(Get,
               bool(const std::string&, bool*, std::string*, leveldb::Status*));
  MOCK_METHOD0(Destroy, leveldb::Status());

  MockDB() : LevelDB(kTestLevelDBClientName) {}
};

class MockDatabaseCaller {
 public:
  MOCK_METHOD1(InitCallback, void(bool));
  MOCK_METHOD1(InitStatusCallback, void(Enums::InitStatus));
  MOCK_METHOD1(DestroyCallback, void(bool));
  MOCK_METHOD1(SaveCallback, void(bool));
  void LoadCallback(bool success,
                    std::unique_ptr<std::vector<TestProto>> entries) {
    LoadCallback1(success, entries.get());
  }
  MOCK_METHOD2(LoadCallback1, void(bool, std::vector<TestProto>*));
  void LoadKeysAndEntriesCallback(
      bool success,
      std::unique_ptr<std::map<std::string, TestProto>> keys_entries) {
    LoadKeysAndEntriesCallback1(success, keys_entries.get());
  }
  MOCK_METHOD2(LoadKeysAndEntriesCallback1,
               void(bool, std::map<std::string, TestProto>*));
  void GetCallback(bool success, std::unique_ptr<TestProto> entry) {
    GetCallback1(success, entry.get());
  }
  MOCK_METHOD2(GetCallback1, void(bool, TestProto*));
};

class OptionsEqMatcher : public MatcherInterface<const Options&> {
 public:
  explicit OptionsEqMatcher(const Options& expected) : expected_(expected) {}

  bool MatchAndExplain(const Options& actual,
                       MatchResultListener* listener) const override {
    return actual.comparator == expected_.comparator &&
           actual.create_if_missing == expected_.create_if_missing &&
           actual.error_if_exists == expected_.error_if_exists &&
           actual.paranoid_checks == expected_.paranoid_checks &&
           actual.env == expected_.env &&
           actual.info_log == expected_.info_log &&
           actual.write_buffer_size == expected_.write_buffer_size &&
           actual.max_open_files == expected_.max_open_files &&
           actual.block_cache == expected_.block_cache &&
           actual.block_size == expected_.block_size &&
           actual.block_restart_interval == expected_.block_restart_interval &&
           actual.max_file_size == expected_.max_file_size &&
           actual.compression == expected_.compression &&
           actual.reuse_logs == expected_.reuse_logs &&
           actual.filter_policy == expected_.filter_policy;
  }

  void DescribeTo(::std::ostream* os) const override {
    *os << "which matches the expected position";
  }

  void DescribeNegationTo(::std::ostream* os) const override {
    *os << "which does not match the expected position";
  }

 private:
  Options expected_;

  DISALLOW_COPY_AND_ASSIGN(OptionsEqMatcher);
};

Matcher<const Options&> OptionsEq(const Options& expected) {
  return MakeMatcher(new OptionsEqMatcher(expected));
}

bool ZeroFilter(const std::string& key) {
  return key == "0";
}

EntryMap GetSmallModel() {
  EntryMap model;

  model["0"].set_id("0");
  model["0"].set_data("http://foo.com/1");

  model["1"].set_id("1");
  model["1"].set_data("http://bar.com/all");

  model["2"].set_id("2");
  model["2"].set_data("http://baz.com/1");

  return model;
}

EntryMap GetRangeTestModel() {
  EntryMap model;

  model["a"].set_id("a");
  model["a"].set_data("entry_a");

  model["b"].set_id("b");
  model["b"].set_data("entry_b");

  model["c"].set_id("c");
  model["c"].set_data("entry_c");

  model["d"].set_id("d");
  model["d"].set_data("entry_d");

  model["e"].set_id("e");
  model["e"].set_data("entry_e");

  return model;
}

}  // namespace

void ExpectEntryPointersEquals(EntryMap expected,
                               const std::vector<TestProto>& actual) {
  EXPECT_EQ(expected.size(), actual.size());
  for (size_t i = 0; i < actual.size(); i++) {
    auto expected_it = expected.find(actual[i].id());
    EXPECT_TRUE(expected_it != expected.end());
    std::string serialized_expected = expected_it->second.SerializeAsString();
    std::string serialized_actual = actual[i].SerializeAsString();
    EXPECT_EQ(serialized_expected, serialized_actual);
    expected.erase(expected_it);
  }
}

class UniqueProtoDatabaseTest : public testing::Test {
 public:
  UniqueProtoDatabaseTest()
      : options_(MakeMatcher(new OptionsEqMatcher(CreateSimpleOptions()))) {}
  void SetUp() override {
    db_.reset(new UniqueProtoDatabase<TestProto>(
        base::ThreadTaskRunnerHandle::Get()));
  }

  void TearDown() override {
    db_.reset();
    base::RunLoop().RunUntilIdle();
  }

  const Matcher<const Options&> options_;
  ScopedTaskEnvironment task_environment_;
  std::unique_ptr<UniqueProtoDatabase<TestProto>> db_;
};

// Test that UniqueProtoDatabase calls Init on the underlying database and that
// the caller's InitCallback is called with the correct value.
TEST_F(UniqueProtoDatabaseTest, TestDBInitSuccess) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  EXPECT_CALL(*mock_db, Init(path, options_, _))
      .WillOnce(Return(leveldb::Status()));

  MockDatabaseCaller caller;
  EXPECT_CALL(caller, InitStatusCallback(Enums::InitStatus::kOK));

  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBInitFailure) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  Options options;
  options.create_if_missing = true;
  EXPECT_CALL(*mock_db, Init(path, OptionsEq(options), _))
      .WillOnce(
          Return(leveldb::Status::IOError(leveldb::Slice(), leveldb::Slice())));

  MockDatabaseCaller caller;
  EXPECT_CALL(caller, InitStatusCallback(Enums::InitStatus::kError));

  db_->InitWithDatabase(mock_db.get(), path, options,
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBDestroySuccess) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  EXPECT_CALL(*mock_db, Init(path, options_, _))
      .WillOnce(Return(leveldb::Status()));

  MockDatabaseCaller caller;
  EXPECT_CALL(caller, InitStatusCallback(Enums::InitStatus::kOK));

  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  EXPECT_CALL(caller, DestroyCallback(true));
  db_->Destroy(base::BindOnce(&MockDatabaseCaller::DestroyCallback,
                              base::Unretained(&caller)));
  EXPECT_CALL(*mock_db, Destroy()).WillOnce(Return(leveldb::Status()));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBDestroyFailure) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  EXPECT_CALL(*mock_db, Init(path, options_, _))
      .WillOnce(Return(leveldb::Status()));

  MockDatabaseCaller caller;
  EXPECT_CALL(caller, InitStatusCallback(Enums::InitStatus::kOK));

  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  EXPECT_CALL(caller, DestroyCallback(false));
  db_->Destroy(base::BindOnce(&MockDatabaseCaller::DestroyCallback,
                              base::Unretained(&caller)));
  EXPECT_CALL(*mock_db, Destroy())
      .WillOnce(
          Return(leveldb::Status::IOError(leveldb::Slice(), leveldb::Slice())));

  base::RunLoop().RunUntilIdle();
}

ACTION_P(AppendLoadEntries, model) {
  std::vector<std::string>* output = arg1;
  for (const auto& pair : model)
    output->push_back(pair.second.SerializeAsString());

  return true;
}

ACTION_P(AppendLoadKeysAndEntries, model) {
  std::map<std::string, std::string>* output = arg1;
  for (const auto& pair : model)
    output->insert(std::make_pair(pair.first, pair.second.SerializeAsString()));

  return true;
}

ACTION_P(VerifyLoadEntries, expected) {
  std::vector<TestProto>* actual = arg1;
  ExpectEntryPointersEquals(expected, *actual);
}

ACTION_P(VerifyLoadKeysAndEntries, expected) {
  std::map<std::string, TestProto>* actual_map = arg1;
  std::vector<TestProto> actual;
  for (const auto& pair : *actual_map)
    actual.push_back(pair.second);
  ExpectEntryPointersEquals(expected, actual);
}

// Test that UniqueProtoDatabase calls Load on the underlying database and that
// the caller's LoadCallback is called with the correct success value. Also
// confirms that on success, the expected entries are passed to the caller's
// LoadCallback.
TEST_F(UniqueProtoDatabaseTest, TestDBLoadSuccess) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;
  EntryMap model = GetSmallModel();

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  EXPECT_CALL(*mock_db, LoadKeysAndEntriesWhile(_, _, _, _, _))
      .WillOnce(AppendLoadKeysAndEntries(model));
  EXPECT_CALL(caller, LoadKeysAndEntriesCallback1(true, _))
      .WillOnce(VerifyLoadKeysAndEntries(testing::ByRef(model)));
  db_->LoadKeysAndEntries(
      base::BindOnce(&MockDatabaseCaller::LoadKeysAndEntriesCallback,
                     base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBLoadFailure) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  EXPECT_CALL(*mock_db, LoadWithFilter(_, _, _, _)).WillOnce(Return(false));
  EXPECT_CALL(caller, LoadCallback1(false, _));
  db_->LoadEntries(base::BindOnce(&MockDatabaseCaller::LoadCallback,
                                  base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBLoadInRangeSuccess) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));
  MockDatabaseCaller caller;
  EntryMap model = GetRangeTestModel();
  EntryMap expected;
  expected["b"] = model["b"];
  expected["c"] = model["c"];
  expected["d"] = model["d"];

  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(db.get(), temp_dir.GetPath(), CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  auto save_entries =
      std::make_unique<ProtoDatabase<TestProto>::KeyEntryVector>();
  std::map<std::string, TestProto> load_keys_entries;
  std::unique_ptr<KeyVector> remove_keys(new KeyVector());

  for (const auto& pair : model)
    save_entries->push_back(std::make_pair(pair.second.id(), pair.second));

  leveldb::Status status;
  EXPECT_CALL(caller, SaveCallback(true));
  db_->UpdateEntries(std::move(save_entries), std::move(remove_keys),
                     base::BindOnce(&MockDatabaseCaller::SaveCallback,
                                    base::Unretained(&caller)));

  EXPECT_CALL(caller, LoadKeysAndEntriesCallback1(true, _))
      .WillOnce(VerifyLoadKeysAndEntries(testing::ByRef(expected)));
  db_->LoadKeysAndEntriesInRange(
      "b", "d",
      base::BindOnce(&MockDatabaseCaller::LoadKeysAndEntriesCallback,
                     base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBLoadInRangeSuccessSameKey) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));
  MockDatabaseCaller caller;
  EntryMap model = GetRangeTestModel();
  EntryMap expected;

  expected["d"] = model["d"];

  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(db.get(), temp_dir.GetPath(), CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  auto save_entries =
      std::make_unique<ProtoDatabase<TestProto>::KeyEntryVector>();
  std::map<std::string, TestProto> load_keys_entries;
  std::unique_ptr<KeyVector> remove_keys(new KeyVector());

  for (const auto& pair : model) {
    save_entries->push_back(std::make_pair(pair.second.id(), pair.second));
  }

  leveldb::Status status;
  EXPECT_CALL(caller, SaveCallback(true));
  db_->UpdateEntries(std::move(save_entries), std::move(remove_keys),
                     base::BindOnce(&MockDatabaseCaller::SaveCallback,
                                    base::Unretained(&caller)));

  EXPECT_CALL(caller, LoadKeysAndEntriesCallback1(true, _))
      .WillOnce(VerifyLoadKeysAndEntries(testing::ByRef(expected)));
  db_->LoadKeysAndEntriesInRange(
      "d", "d",
      base::BindOnce(&MockDatabaseCaller::LoadKeysAndEntriesCallback,
                     base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

ACTION_P(SetGetEntry, model) {
  const std::string& key = arg0;
  bool* found = arg1;
  std::string* output = arg2;
  auto it = model.find(key);
  if (it == model.end()) {
    *found = false;
  } else {
    *found = true;
    *output = it->second.SerializeAsString();
  }
  return true;
}

ACTION_P(VerifyGetEntry, expected) {
  TestProto* actual = arg1;
  EXPECT_EQ(expected.SerializeAsString(), actual->SerializeAsString());
}

TEST_F(UniqueProtoDatabaseTest, TestDBGetSuccess) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;
  EntryMap model = GetSmallModel();

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  std::string key("1");
  ASSERT_TRUE(model.count(key));
  EXPECT_CALL(*mock_db, Get(key, _, _, _)).WillOnce(SetGetEntry(model));
  EXPECT_CALL(caller, GetCallback1(true, _))
      .WillOnce(VerifyGetEntry(model[key]));
  db_->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback,
                                    base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBRemoveKeys) {
  const std::string kTestPrefix = "test_prefix";
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(*mock_db, UpdateWithRemoveFilter(_, _, kTestPrefix, _))
      .WillOnce(Return(true));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();

  base::RunLoop run_update_entries;
  auto expect_update_success = base::BindOnce(
      [](base::OnceClosure signal, bool success) {
        EXPECT_TRUE(success);
        std::move(signal).Run();
      },
      run_update_entries.QuitClosure());
  db_->RemoveKeysForTesting(
      base::BindRepeating([](const std::string& str) { return true; }),
      kTestPrefix, std::move(expect_update_success));
  run_update_entries.Run();
}

class UniqueProtoDatabaseLevelDBTest : public testing::Test {
 public:
  void TearDown() override { base::RunLoop().RunUntilIdle(); }

 private:
  ScopedTaskEnvironment scoped_task_environment_;
};

TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBSaveAndLoadKeys) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  base::Thread db_thread("dbthread");
  ASSERT_TRUE(db_thread.Start());
  std::unique_ptr<UniqueProtoDatabase<TestProto>> db(
      new UniqueProtoDatabase<TestProto>(db_thread.task_runner()));

  MockDatabaseCaller caller;
  EXPECT_CALL(caller, InitCallback(true));

  db->Init(kTestLevelDBClientName, temp_dir.GetPath(), CreateSimpleOptions(),
           base::BindOnce(&MockDatabaseCaller::InitCallback,
                          base::Unretained(&caller)));

  base::RunLoop run_update_entries;
  auto expect_update_success = base::BindOnce(
      [](base::OnceClosure signal, bool success) {
        EXPECT_TRUE(success);
        std::move(signal).Run();
      },
      run_update_entries.QuitClosure());
  TestProto test_proto;
  test_proto.set_data("some data");
  ProtoDatabase<TestProto>::KeyEntryVector data_set(
      {{"0", test_proto}, {"1", test_proto}, {"2", test_proto}});
  db->UpdateEntries(
      std::make_unique<ProtoDatabase<TestProto>::KeyEntryVector>(data_set),
      std::make_unique<std::vector<std::string>>(),
      std::move(expect_update_success));
  run_update_entries.Run();

  base::RunLoop run_load_keys;
  auto verify_loaded_keys = base::BindOnce(
      [](base::OnceClosure signal, bool success,
         std::unique_ptr<std::vector<std::string>> keys) {
        EXPECT_TRUE(success);
        EXPECT_THAT(*keys, UnorderedElementsAre("0", "1", "2"));
        std::move(signal).Run();
      },
      run_load_keys.QuitClosure());
  db->LoadKeys(std::move(verify_loaded_keys));
  run_load_keys.Run();

  // Shutdown database.
  db.reset();
  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBGetNotFound) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;
  EntryMap model = GetSmallModel();

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  std::string key("does_not_exist");
  ASSERT_FALSE(model.count(key));
  EXPECT_CALL(*mock_db, Get(key, _, _, _)).WillOnce(SetGetEntry(model));
  EXPECT_CALL(caller, GetCallback1(true, nullptr));
  db_->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback,
                                    base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBGetFailure) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;
  EntryMap model = GetSmallModel();

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  std::string key("does_not_exist");
  ASSERT_FALSE(model.count(key));
  EXPECT_CALL(*mock_db, Get(key, _, _, _)).WillOnce(Return(false));
  EXPECT_CALL(caller, GetCallback1(false, nullptr));
  db_->GetEntry(key, base::BindOnce(&MockDatabaseCaller::GetCallback,
                                    base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

ACTION_P(VerifyUpdateEntries, expected) {
  const KeyValueVector actual = arg0;
  // Create a vector of TestProto from |actual| to reuse the comparison
  // function.
  std::vector<TestProto> extracted_entries;
  for (const auto& pair : actual) {
    TestProto entry;
    if (!entry.ParseFromString(pair.second)) {
      ADD_FAILURE() << "Unable to deserialize the protobuf";
      return false;
    }

    extracted_entries.push_back(entry);
  }

  ExpectEntryPointersEquals(expected, extracted_entries);
  return true;
}

// Test that UniqueProtoDatabase calls Save on the underlying database with the
// correct entries to save and that the caller's SaveCallback is called with the
// correct success value.
TEST_F(UniqueProtoDatabaseTest, TestDBSaveSuccess) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;
  EntryMap model = GetSmallModel();

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  std::unique_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries(
      new ProtoDatabase<TestProto>::KeyEntryVector());
  for (const auto& pair : model)
    entries->push_back(std::make_pair(pair.second.id(), pair.second));

  std::unique_ptr<KeyVector> keys_to_remove(new KeyVector());

  EXPECT_CALL(*mock_db, Save(_, _, _)).WillOnce(VerifyUpdateEntries(model));
  EXPECT_CALL(caller, SaveCallback(true));
  db_->UpdateEntries(std::move(entries), std::move(keys_to_remove),
                     base::BindOnce(&MockDatabaseCaller::SaveCallback,
                                    base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBSaveFailure) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;
  std::unique_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries(
      new ProtoDatabase<TestProto>::KeyEntryVector());
  std::unique_ptr<KeyVector> keys_to_remove(new KeyVector());

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  EXPECT_CALL(*mock_db, Save(_, _, _)).WillOnce(Return(false));
  EXPECT_CALL(caller, SaveCallback(false));
  db_->UpdateEntries(std::move(entries), std::move(keys_to_remove),
                     base::BindOnce(&MockDatabaseCaller::SaveCallback,
                                    base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

// Test that UniqueProtoDatabase calls Save on the underlying database with the
// correct entries to delete and that the caller's SaveCallback is called with
// the correct success value.
TEST_F(UniqueProtoDatabaseTest, TestDBRemoveSuccess) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;
  EntryMap model = GetSmallModel();

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  std::unique_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries(
      new ProtoDatabase<TestProto>::KeyEntryVector());
  std::unique_ptr<KeyVector> keys_to_remove(new KeyVector());
  for (const auto& pair : model)
    keys_to_remove->push_back(pair.second.id());

  KeyVector keys_copy(*keys_to_remove.get());
  EXPECT_CALL(*mock_db, Save(_, keys_copy, _)).WillOnce(Return(true));
  EXPECT_CALL(caller, SaveCallback(true));
  db_->UpdateEntries(std::move(entries), std::move(keys_to_remove),
                     base::BindOnce(&MockDatabaseCaller::SaveCallback,
                                    base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

TEST_F(UniqueProtoDatabaseTest, TestDBRemoveFailure) {
  base::FilePath path(FILE_PATH_LITERAL("/fake/path"));

  auto mock_db = std::make_unique<MockDB>();
  MockDatabaseCaller caller;
  std::unique_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries(
      new ProtoDatabase<TestProto>::KeyEntryVector());
  std::unique_ptr<KeyVector> keys_to_remove(new KeyVector());

  EXPECT_CALL(*mock_db, Init(_, options_, _));
  EXPECT_CALL(caller, InitStatusCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitStatusCallback,
                                       base::Unretained(&caller)));

  EXPECT_CALL(*mock_db, Save(_, _, _)).WillOnce(Return(false));
  EXPECT_CALL(caller, SaveCallback(false));
  db_->UpdateEntries(std::move(entries), std::move(keys_to_remove),
                     base::BindOnce(&MockDatabaseCaller::SaveCallback,
                                    base::Unretained(&caller)));

  base::RunLoop().RunUntilIdle();
}

// This tests that normal usage of the real database does not cause any
// threading violations.
TEST(UniqueProtoDatabaseThreadingTest, TestDBDestruction) {
  ScopedTaskEnvironment scoped_task_environment;

  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  base::Thread db_thread("dbthread");
  ASSERT_TRUE(db_thread.Start());

  std::unique_ptr<UniqueProtoDatabase<TestProto>> db(
      new UniqueProtoDatabase<TestProto>(db_thread.task_runner()));

  MockDatabaseCaller caller;
  EXPECT_CALL(caller, InitCallback(_));
  base::RunLoop init_loop;
  db->Init(kTestLevelDBClientName, temp_dir.GetPath(), CreateSimpleOptions(),
           base::BindOnce(
               [](MockDatabaseCaller* caller, base::OnceClosure closure,
                  bool success) {
                 caller->InitCallback(success);
                 std::move(closure).Run();
               },
               &caller, init_loop.QuitClosure()));
  init_loop.Run();

  db.reset();
  base::RunLoop run_loop;
  db_thread.task_runner()->PostTaskAndReply(FROM_HERE, base::DoNothing(),
                                            run_loop.QuitClosure());
  run_loop.Run();
}

// This tests that normal usage of the real database does not cause any
// threading violations.
TEST(UniqueProtoDatabaseThreadingTest, TestDBDestroy) {
  ScopedTaskEnvironment scoped_task_environment;

  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  base::Thread db_thread("dbthread");
  ASSERT_TRUE(db_thread.Start());

  std::unique_ptr<UniqueProtoDatabase<TestProto>> db(
      new UniqueProtoDatabase<TestProto>(db_thread.task_runner()));

  MockDatabaseCaller caller;
  EXPECT_CALL(caller, InitCallback(_));
  base::RunLoop init_loop;
  db->Init(kTestLevelDBClientName, temp_dir.GetPath(), CreateSimpleOptions(),
           base::BindOnce(
               [](MockDatabaseCaller* caller, base::OnceClosure closure,
                  bool success) {
                 caller->InitCallback(success);
                 std::move(closure).Run();
               },
               &caller, init_loop.QuitClosure()));
  init_loop.Run();

  EXPECT_CALL(caller, DestroyCallback(_));
  db->Destroy(base::BindOnce(&MockDatabaseCaller::DestroyCallback,
                             base::Unretained(&caller)));

  base::RunLoop run_loop;
  db_thread.task_runner()->PostTaskAndReply(FROM_HERE, base::DoNothing(),
                                            run_loop.QuitClosure());
  run_loop.Run();

  // Verify the db is actually destroyed.
  EXPECT_FALSE(base::PathExists(temp_dir.GetPath()));
}

// Test that the LevelDB properly saves entries and that load returns the saved
// entries. If |close_after_save| is true, the database will be closed after
// saving and then re-opened to ensure that the data is properly persisted.
void TestLevelDBSaveAndLoad(bool close_after_save) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  EntryMap model = GetSmallModel();

  KeyValueVector save_entries;
  std::vector<std::string> load_entries;
  KeyVector remove_keys;

  for (const auto& pair : model) {
    save_entries.push_back(
        std::make_pair(pair.second.id(), pair.second.SerializeAsString()));
  }

  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));
  EXPECT_TRUE(db->Init(temp_dir.GetPath(), CreateSimpleOptions()));
  leveldb::Status status;
  EXPECT_TRUE(db->Save(save_entries, remove_keys, &status));

  if (close_after_save) {
    db.reset(new LevelDB(kTestLevelDBClientName));
    EXPECT_TRUE(db->Init(temp_dir.GetPath(), CreateSimpleOptions()));
  }

  EXPECT_TRUE(db->Load(&load_entries));

  // Convert the strings back to TestProto.
  std::vector<TestProto> loaded_protos;
  for (const auto& serialized_entry : load_entries) {
    TestProto entry;
    ASSERT_TRUE(entry.ParseFromString(serialized_entry));
    loaded_protos.push_back(entry);
  }

  ExpectEntryPointersEquals(model, loaded_protos);
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBSaveAndLoad) {
  TestLevelDBSaveAndLoad(false);
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBCloseAndReopen) {
  TestLevelDBSaveAndLoad(true);
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBLoadWithFilter) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  EntryMap model = GetSmallModel();

  KeyValueVector save_entries;
  std::vector<std::string> load_entries;
  KeyVector remove_keys;

  for (const auto& pair : model) {
    save_entries.push_back(
        std::make_pair(pair.second.id(), pair.second.SerializeAsString()));
  }

  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));
  EXPECT_TRUE(db->Init(temp_dir.GetPath(), CreateSimpleOptions()));
  leveldb::Status status;
  EXPECT_TRUE(db->Save(save_entries, remove_keys, &status));

  EXPECT_TRUE(
      db->LoadWithFilter(base::BindRepeating(&ZeroFilter), &load_entries));

  EXPECT_EQ(load_entries.size(), 1u);
  TestProto entry;
  ASSERT_TRUE(entry.ParseFromString(load_entries[0]));
  EXPECT_EQ(entry.SerializeAsString(), model["0"].SerializeAsString());
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBLoadKeysAndEntries) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  EntryMap model = GetSmallModel();

  KeyValueVector save_entries;
  std::map<std::string, std::string> load_keys_entries;
  KeyVector remove_keys;

  for (const auto& pair : model) {
    save_entries.push_back(
        std::make_pair(pair.second.id(), pair.second.SerializeAsString()));
  }

  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));
  EXPECT_TRUE(db->Init(temp_dir.GetPath(), CreateSimpleOptions()));
  leveldb::Status status;
  EXPECT_TRUE(db->Save(save_entries, remove_keys, &status));

  EXPECT_TRUE(db->LoadKeysAndEntries(&load_keys_entries));

  EXPECT_EQ(load_keys_entries.size(), model.size());
  for (const auto& pair : load_keys_entries) {
    TestProto entry;
    ASSERT_TRUE(entry.ParseFromString(pair.second));
    EXPECT_EQ(entry.SerializeAsString(), model[pair.first].SerializeAsString());
  }
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBLoadKeysAndEntriesWhile) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  EntryMap model = GetRangeTestModel();
  EntryMap expected;
  expected["b"] = model["b"];
  expected["c"] = model["c"];
  expected["d"] = model["d"];

  KeyValueVector save_entries;
  std::map<std::string, std::string> load_keys_entries;
  KeyVector remove_keys;

  for (const auto& pair : model) {
    save_entries.push_back(
        std::make_pair(pair.second.id(), pair.second.SerializeAsString()));
  }

  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));
  EXPECT_TRUE(db->Init(temp_dir.GetPath(), CreateSimpleOptions()));
  leveldb::Status status;
  EXPECT_TRUE(db->Save(save_entries, remove_keys, &status));

  EXPECT_TRUE(db->LoadKeysAndEntriesWhile(
      LevelDB::KeyFilter(), &load_keys_entries, leveldb::ReadOptions(), "b",
      base::BindRepeating(
          [](const std::string& range_end, const std::string& key) {
            return key.compare(range_end) <= 0;
          },
          "d")));

  EXPECT_EQ(load_keys_entries.size(), expected.size());
  for (const auto& pair : load_keys_entries) {
    TestProto entry;
    ASSERT_TRUE(entry.ParseFromString(pair.second));
    EXPECT_EQ(entry.SerializeAsString(),
              expected[pair.first].SerializeAsString());
  }
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBInitFail) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  Options options;
  options.create_if_missing = false;
  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));

  KeyValueVector save_entries;
  std::vector<std::string> load_entries;
  KeyVector remove_keys;

  EXPECT_FALSE(db->Init(temp_dir.GetPath(), options));
  EXPECT_FALSE(db->Load(&load_entries));
  leveldb::Status status;
  EXPECT_FALSE(db->Save(save_entries, remove_keys, &status));
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestMemoryDatabase) {
  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));

  std::vector<std::string> load_entries;

  ASSERT_TRUE(db->Init(base::FilePath(), CreateSimpleOptions()));

  ASSERT_TRUE(db->Load(&load_entries));
  EXPECT_EQ(0u, load_entries.size());

  KeyValueVector save_entries(1, std::make_pair("foo", "bar"));
  KeyVector remove_keys;

  leveldb::Status status;
  ASSERT_TRUE(db->Save(save_entries, remove_keys, &status));

  std::vector<std::string> second_load_entries;

  ASSERT_TRUE(db->Load(&second_load_entries));
  EXPECT_EQ(1u, second_load_entries.size());
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestCorruptDBReset) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Create a database, write some data, and then close the db.
  {
    LevelDB db(kTestLevelDBClientName);
    ASSERT_TRUE(db.Init(temp_dir.GetPath(), CreateSimpleOptions()));

    base::StringPairs pairs_to_save;
    pairs_to_save.push_back(std::make_pair("TheKey", "KeyValue"));
    std::vector<std::string> keys_to_remove;
    leveldb::Status status;
    ASSERT_TRUE(db.Save(pairs_to_save, keys_to_remove, &status));
  }

  EXPECT_TRUE(leveldb_chrome::CorruptClosedDBForTesting(temp_dir.GetPath()));

  // Open the corrupt database which should succeed, but will destroy the
  // existing corrupt database.
  LevelDB db(kTestLevelDBClientName);
  leveldb_env::Options options = CreateSimpleOptions();
  options.paranoid_checks = true;
  ASSERT_TRUE(db.Init(temp_dir.GetPath(), options));
  bool found = false;
  std::string value;
  leveldb::Status status;
  ASSERT_TRUE(db.Get("TheKey", &found, &value, &status));
  ASSERT_EQ("", value);
  ASSERT_FALSE(found);
}

TEST_F(UniqueProtoDatabaseLevelDBTest, TestDBDeleteWithFilter) {
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  EntryMap model = GetSmallModel();

  KeyValueVector save_entries;
  std::vector<std::string> load_entries;
  KeyVector remove_keys;

  for (const auto& pair : model) {
    save_entries.push_back(
        std::make_pair(pair.second.id(), pair.second.SerializeAsString()));
  }

  std::unique_ptr<LevelDB> db(new LevelDB(kTestLevelDBClientName));
  EXPECT_TRUE(db->Init(temp_dir.GetPath(), CreateSimpleOptions()));
  leveldb::Status status;
  EXPECT_TRUE(
      db->UpdateWithRemoveFilter(save_entries, LevelDB::KeyFilter(), &status));

  // Make sure the "0" entry is in database.
  EXPECT_TRUE(
      db->LoadWithFilter(base::BindRepeating(&ZeroFilter), &load_entries));
  EXPECT_EQ(load_entries.size(), 1u);

  // Delete "0" entry.
  save_entries.clear();
  EXPECT_TRUE(db->UpdateWithRemoveFilter(
      save_entries, base::BindRepeating(&ZeroFilter), &status));

  // Make sure the "0" entry is not there.
  load_entries.clear();
  EXPECT_TRUE(
      db->LoadWithFilter(base::BindRepeating(&ZeroFilter), &load_entries));
  EXPECT_EQ(load_entries.size(), 0u);
}

}  // namespace leveldb_proto
