// Copyright 2017 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.

#ifndef SRC_LEDGER_BIN_STORAGE_IMPL_STORAGE_TEST_UTILS_H_
#define SRC_LEDGER_BIN_STORAGE_IMPL_STORAGE_TEST_UTILS_H_

#include <lib/fsl/socket/strings.h>

#include <string>

#include "peridot/lib/rng/random.h"
#include "src/ledger/bin/storage/impl/btree/tree_node.h"
#include "src/ledger/bin/storage/public/page_storage.h"
#include "src/ledger/bin/storage/public/types.h"
#include "src/ledger/bin/testing/test_with_environment.h"

namespace storage {

// A sufficiently large delay, such that if a storagemethod posts a delayed
// task, the task will be due after associated amount of time.
inline constexpr zx::duration kSufficientDelay = zx::hour(1);

// Enum describing the expected behavior for identifier, allowing or preventing
// to be inlined values.
enum class InlineBehavior {
  ALLOW,
  PREVENT,
};

// This class stores an object, computes its identifier and
// provides accessor to transform into a data source and data chunks.
class ObjectData {
 public:
  explicit ObjectData(std::string value)
      : ObjectData(value, InlineBehavior::ALLOW) {}
  explicit ObjectData(std::string value, InlineBehavior inline_behavior)
      : ObjectData(value, ObjectType::BLOB, inline_behavior) {}
  explicit ObjectData(std::string value, ObjectType object_type,
                      InlineBehavior inline_behavior);
  std::unique_ptr<DataSource> ToDataSource();
  std::unique_ptr<DataSource::DataChunk> ToChunk();
  std::unique_ptr<Piece> ToPiece();

  const std::string value;
  const size_t size;
  const ObjectIdentifier object_identifier;
};

// Computes the object digest for the given content. If |inline_behavior| is
// InlineBehavior::PREVENT, resize |content| so that it cannot be inlined.
ObjectDigest MakeObjectDigest(
    std::string content,
    InlineBehavior inline_behavior = InlineBehavior::ALLOW);

// Computes the object identifier for the given content. If |inline_behavior| is
// InlineBehavior::PREVENT, resize |content| so that it cannot be inlined.
ObjectIdentifier MakeObjectIdentifier(
    std::string content,
    InlineBehavior inline_behavior = InlineBehavior::ALLOW);

// Splits the given content in chunks and calls the callback on each of them.
// Returns the object identifier for the root piece.
ObjectIdentifier MakeSplitMap(
    std::string content,
    fit::function<void(ObjectIdentifier object_identifier, std::string)>
        callback);

// Returns a random string of the given length.
std::string RandomString(rng::Random* random, size_t size);

// Create a new random commit id.
CommitId RandomCommitId(rng::Random* random);

// Create a new random object digest.
ObjectDigest RandomObjectDigest(rng::Random* random);

// Create a new random object identifier.
ObjectIdentifier RandomObjectIdentifier(rng::Random* random);

// Creates and returns a new EntryChange adding or updating the entry with the
// given information.
EntryChange NewEntryChange(std::string key, std::string object_digest,
                           KeyPriority priority);

// Creates and returns a new EntryChange removing the entry with the given key.
EntryChange NewRemoveEntryChange(std::string key);

// A TestLoopFixture providing some additional utility functions on PageStorage.
//
// All utility functions in this class return an |AssertionResult| meaning that
// they can be used in an EXPECT/ASSERT_TRUE: E.g.
//     ASSERT_TRUE(AddObject("value", &object));
// or an EXPECT/ASSERT_FALSE if the function is expected to fail.
//     ASSERT_FALSE(AddObject("value", &object));
class StorageTest : public ledger::TestWithEnvironment {
 protected:
  StorageTest();

  ~StorageTest() override;

  virtual PageStorage* GetStorage() = 0;

  // Adds a new BLOB object with the given value in the page storage and updates
  // |object| with the new value.
  ::testing::AssertionResult AddObject(std::string value,
                                       std::unique_ptr<const Object>* object);

  // Creates a vector of entries, each of which has a key from "key00" to
  // "keyXX" where XX is |size-1|. A new value is created for each entry and the
  // corresponding object_digest is set on the entry. |entries| vector will be
  // swapped with the result.
  ::testing::AssertionResult CreateEntries(size_t size,
                                           std::vector<Entry>* entries);

  // Creates a vector of entries, each of which has a key "keyXX", were "XX" is
  // taken from the |values| vector. A new value is created for each entry and
  // the corresponding object_digest is set on the entry. |entries| vector will
  // be swapped with the result.
  ::testing::AssertionResult CreateEntries(std::vector<size_t> values,
                                           std::vector<Entry>* entries);

  // Creates a vector of entry changes adding or updating the given number of
  // entries. See |CreateEntries| for information on the created entries.
  // |changes| vector will be swapped with the result.
  ::testing::AssertionResult CreateEntryChanges(
      size_t size, std::vector<EntryChange>* changes);

  // Creates a vector of entry changes adding or updating the given number of
  // entries. See |CreateEntries| for information on the created entries.
  // |changes| vector will be swapped with the result. If |deletion| is true,
  // the changes will be deletions, otherwise the changes will be updates.
  ::testing::AssertionResult CreateEntryChanges(
      std::vector<size_t> values, std::vector<EntryChange>* changes,
      bool deletion = false);

  // Creates an empty tree node and updates |empty_node_identifier| with the
  // result.
  ::testing::AssertionResult GetEmptyNodeIdentifier(
      ObjectIdentifier* empty_node_identifier);

  // Returns the tree node corresponding to the given id.
  ::testing::AssertionResult CreateNodeFromIdentifier(
      ObjectIdentifier identifier,
      std::unique_ptr<const btree::TreeNode>* node);

  // Creates a new tree node from the given entries and children and updates
  // |node| with the result.
  ::testing::AssertionResult CreateNodeFromEntries(
      const std::vector<Entry>& entries,
      const std::map<size_t, ObjectIdentifier>& children,
      std::unique_ptr<const btree::TreeNode>* node);

  // Creates a BTree applying changes from the base node and gives back the
  // digest of its new root node.
  ::testing::AssertionResult CreateTreeFromChanges(
      const ObjectIdentifier& base_node_identifier,
      const std::vector<EntryChange>& entries,
      ObjectIdentifier* new_root_identifier);

 private:
  FXL_DISALLOW_COPY_AND_ASSIGN(StorageTest);
};

}  // namespace storage

#endif  // SRC_LEDGER_BIN_STORAGE_IMPL_STORAGE_TEST_UTILS_H_
