// Copyright 2018 The Fuchsia 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 <lib/callback/set_when_called.h>

#include <memory>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "src/ledger/bin/encryption/fake/fake_encryption_service.h"
#include "src/ledger/bin/storage/fake/fake_db.h"
#include "src/ledger/bin/storage/impl/journal_impl.h"
#include "src/ledger/bin/storage/impl/storage_test_utils.h"
#include "src/ledger/bin/storage/public/constants.h"
#include "src/ledger/bin/testing/test_with_environment.h"

namespace storage {
namespace {

using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::SizeIs;

class JournalTest : public ledger::TestWithEnvironment {
 public:
  JournalTest()
      : encryption_service_(dispatcher()),
        page_storage_(&environment_, &encryption_service_,
                      std::make_unique<storage::fake::FakeDb>(dispatcher()),
                      "page_id"),
        object_identifier_(0u, 0u, MakeObjectDigest("value")) {}

  ~JournalTest() override {}

  // Test:
  void SetUp() override {
    Status status;
    bool called;
    page_storage_.Init(
        callback::Capture(callback::SetWhenCalled(&called), &status));
    RunLoopUntilIdle();
    ASSERT_TRUE(called);
    ASSERT_EQ(Status::OK, status);

    page_storage_.GetCommit(kFirstPageCommitId,
                            callback::Capture(callback::SetWhenCalled(&called),
                                              &status, &first_commit_));
    RunLoopUntilIdle();
    ASSERT_TRUE(called);
    ASSERT_EQ(Status::OK, status);
  }

  // Casts the given |Journal| to |JournalImpl| and updates |journal_| to have
  // this value.
  void SetJournal(std::unique_ptr<Journal> journal) {
    journal_ = std::unique_ptr<JournalImpl>(
        static_cast<JournalImpl*>(journal.release()));
  }

  std::vector<Entry> GetCommitContents(const Commit& commit) {
    bool called;
    Status status;
    std::vector<Entry> result;
    auto on_next = [&result](Entry e) {
      result.push_back(e);
      return true;
    };
    page_storage_.GetCommitContents(
        commit, "", std::move(on_next),
        callback::Capture(callback::SetWhenCalled(&called), &status));
    RunLoopUntilIdle();
    EXPECT_TRUE(called);
    EXPECT_EQ(Status::OK, status);
    return result;
  }

 protected:
  encryption::FakeEncryptionService encryption_service_;
  PageStorageImpl page_storage_;

  ObjectIdentifier object_identifier_;

  std::unique_ptr<JournalImpl> journal_;

  std::unique_ptr<const Commit> first_commit_;

  FXL_DISALLOW_COPY_AND_ASSIGN(JournalTest);
};

TEST_F(JournalTest, CommitEmptyJournal) {
  SetJournal(JournalImpl::Simple(&environment_, &page_storage_,
                                 first_commit_->Clone()));
  bool called;
  Status status;
  std::unique_ptr<const Commit> commit;
  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  // Commiting an empty journal should result in a successful status, but a null
  // commit.
  ASSERT_EQ(Status::OK, status);
  ASSERT_EQ(nullptr, commit);
}

TEST_F(JournalTest, JournalsPutDeleteCommit) {
  SetJournal(JournalImpl::Simple(&environment_, &page_storage_,
                                 first_commit_->Clone()));
  journal_->Put("key", object_identifier_, KeyPriority::EAGER);

  bool called;
  Status status;
  std::unique_ptr<const Commit> commit;
  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, commit);

  std::vector<Entry> entries = GetCommitContents(*commit);
  ASSERT_THAT(entries, SizeIs(1));
  EXPECT_EQ("key", entries[0].key);
  EXPECT_EQ(object_identifier_, entries[0].object_identifier);
  EXPECT_EQ(KeyPriority::EAGER, entries[0].priority);

  // Ledger's content is now a single entry "key" -> "value". Delete it.
  SetJournal(
      JournalImpl::Simple(&environment_, &page_storage_, std::move(commit)));
  journal_->Delete("key");

  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, commit);

  ASSERT_THAT(GetCommitContents(*commit), ElementsAre());
}

TEST_F(JournalTest, JournalsPutRollback) {
  SetJournal(JournalImpl::Simple(&environment_, &page_storage_,
                                 first_commit_->Clone()));
  journal_->Put("key", object_identifier_, KeyPriority::EAGER);

  // The journal was not committed: the contents of page storage should not have
  // changed.
  journal_.reset();

  std::vector<std::unique_ptr<const Commit>> heads;
  Status status = page_storage_.GetHeadCommits(&heads);
  ASSERT_EQ(Status::OK, status);
  ASSERT_THAT(heads, SizeIs(1));
  EXPECT_EQ(kFirstPageCommitId, heads[0]->GetId());
}

TEST_F(JournalTest, MultiplePutsDeletes) {
  int size = 3;
  SetJournal(JournalImpl::Simple(&environment_, &page_storage_,
                                 first_commit_->Clone()));
  bool called;
  Status status;
  // Insert keys {"0", "1", "2"}. Also insert key "0" a second time, with a
  // different value, and delete a non-existing key.
  for (int i = 0; i < size; i++) {
    journal_->Put(std::to_string(i), object_identifier_, KeyPriority::EAGER);
  }
  journal_->Delete("notfound");

  ObjectIdentifier object_identifier_2(0u, 0u,
                                       MakeObjectDigest("another value"));
  journal_->Put("0", object_identifier_2, KeyPriority::EAGER);

  std::unique_ptr<const Commit> commit;
  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit));

  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, commit);

  std::vector<Entry> entries = GetCommitContents(*commit);
  ASSERT_THAT(entries, SizeIs(size));
  for (int i = 0; i < size; i++) {
    EXPECT_EQ(std::to_string(i), entries[i].key);
    if (i == 0) {
      EXPECT_EQ(object_identifier_2, entries[i].object_identifier);
    } else {
      EXPECT_EQ(object_identifier_, entries[i].object_identifier);
    }
    EXPECT_EQ(KeyPriority::EAGER, entries[i].priority);
  }

  // Delete keys {"0", "2"}. Also insert a key, that is deleted on the same
  // journal.
  SetJournal(
      JournalImpl::Simple(&environment_, &page_storage_, std::move(commit)));
  journal_->Delete("0");
  journal_->Delete("2");
  journal_->Put("tmp", object_identifier_, KeyPriority::EAGER);
  journal_->Delete("tmp");

  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit));

  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, commit);

  // Check that there is only one entry left.
  entries = GetCommitContents(*commit);
  ASSERT_THAT(entries, SizeIs(1));
  EXPECT_EQ("1", entries[0].key);
  EXPECT_EQ(object_identifier_, entries[0].object_identifier);
  EXPECT_EQ(KeyPriority::EAGER, entries[0].priority);
}

TEST_F(JournalTest, PutClear) {
  int size = 3;
  SetJournal(JournalImpl::Simple(&environment_, &page_storage_,
                                 first_commit_->Clone()));
  bool called;
  Status status;
  // Insert keys {"0", "1", "2"}.
  for (int i = 0; i < size; i++) {
    journal_->Put(std::to_string(i), object_identifier_, KeyPriority::EAGER);
  }

  std::unique_ptr<const Commit> commit;
  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit));

  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, commit);

  ASSERT_THAT(GetCommitContents(*commit), SizeIs(size));

  // Clear the contents.
  SetJournal(
      JournalImpl::Simple(&environment_, &page_storage_, std::move(commit)));
  journal_->Clear();

  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit));
  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, commit);

  EXPECT_THAT(GetCommitContents(*commit), IsEmpty());
}

TEST_F(JournalTest, MergeJournal) {
  // Create 2 commits from the |kFirstPageCommitId|, one with a key "0", and one
  // with a key "1".
  SetJournal(JournalImpl::Simple(&environment_, &page_storage_,
                                 first_commit_->Clone()));
  journal_->Put("0", object_identifier_, KeyPriority::EAGER);

  bool called;
  Status status;
  std::unique_ptr<const Commit> commit_0;
  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit_0));
  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, commit_0);

  SetJournal(JournalImpl::Simple(&environment_, &page_storage_,
                                 first_commit_->Clone()));
  journal_->Put("1", object_identifier_, KeyPriority::EAGER);

  std::unique_ptr<const Commit> commit_1;
  journal_->Commit(
      callback::Capture(callback::SetWhenCalled(&called), &status, &commit_1));
  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, commit_1);

  // Create a merge journal, adding only a key "2".
  SetJournal(JournalImpl::Merge(&environment_, &page_storage_,
                                std::move(commit_0), std::move(commit_1)));
  journal_->Put("2", object_identifier_, KeyPriority::EAGER);

  std::unique_ptr<const Commit> merge_commit;
  journal_->Commit(callback::Capture(callback::SetWhenCalled(&called), &status,
                                     &merge_commit));
  RunLoopUntilIdle();
  ASSERT_TRUE(called);
  ASSERT_EQ(Status::OK, status);
  ASSERT_NE(nullptr, merge_commit);

  // Expect the contents to have two keys: "0" and "2".
  std::vector<Entry> entries = GetCommitContents(*merge_commit);
  entries = GetCommitContents(*merge_commit);
  ASSERT_THAT(entries, SizeIs(2));
  EXPECT_EQ("0", entries[0].key);
  EXPECT_EQ(object_identifier_, entries[0].object_identifier);
  EXPECT_EQ(KeyPriority::EAGER, entries[0].priority);

  EXPECT_EQ("2", entries[1].key);
  EXPECT_EQ(object_identifier_, entries[1].object_identifier);
  EXPECT_EQ(KeyPriority::EAGER, entries[1].priority);
}

}  // namespace
}  // namespace storage
