// 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/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.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::MessageLoop;
using base::ScopedTempDir;
using leveldb_env::Options;
using testing::Invoke;
using testing::MakeMatcher;
using testing::MatchResultListener;
using testing::Matcher;
using testing::MatcherInterface;
using testing::Return;
using testing::UnorderedElementsAre;
using testing::_;

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_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_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(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";
}

}  // namespace

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;
}

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 {
    main_loop_.reset(new MessageLoop());
    db_.reset(new UniqueProtoDatabase<TestProto>(main_loop_->task_runner()));
  }

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

  const Matcher<const Options&> options_;
  std::unique_ptr<UniqueProtoDatabase<TestProto>> db_;
  std::unique_ptr<MessageLoop> main_loop_;
};

// 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, InitCallback(true));

  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(false));

  db_->InitWithDatabase(mock_db.get(), path, options,
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(true));

  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(true));

  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       base::Unretained(&caller)));

  EXPECT_CALL(*mock_db, LoadKeysAndEntriesWithFilter(_, _, _, _))
      .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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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();
}

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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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();
}

class UniqueProtoDatabaseLevelDBTest : public testing::Test {
 public:
  void SetUp() override { main_loop_.reset(new MessageLoop()); }

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

 private:
  std::unique_ptr<MessageLoop> main_loop_;
};

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()));

  auto expect_init_success =
      base::BindOnce([](bool success) { EXPECT_TRUE(success); });
  db->Init(kTestLevelDBClientName, temp_dir.GetPath(), CreateSimpleOptions(),
           std::move(expect_init_success));

  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 run_destruction;
  db_thread.task_runner()->PostTaskAndReply(FROM_HERE, base::DoNothing(),
                                            run_destruction.QuitClosure());
  run_destruction.Run();
}

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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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, InitCallback(_));
  db_->InitWithDatabase(mock_db.get(), path, CreateSimpleOptions(),
                        base::BindOnce(&MockDatabaseCaller::InitCallback,
                                       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) {
  base::MessageLoop main_loop;

  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) {
  base::MessageLoop main_loop;

  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)));

  db.reset();

  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, 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
