// Copyright 2021 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/strings/internal/cord_rep_btree.h"

#include <cmath>
#include <deque>
#include <iostream>
#include <string>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/cleanup/cleanup.h"
#include "absl/strings/internal/cord_data_edge.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_test_util.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {

class CordRepBtreeTestPeer {
 public:
  static void SetEdge(CordRepBtree* node, size_t idx, CordRep* edge) {
    node->edges_[idx] = edge;
  }
  static void AddEdge(CordRepBtree* node, CordRep* edge) {
    node->edges_[node->fetch_add_end(1)] = edge;
  }
};

namespace {

using ::absl::cordrep_testing::AutoUnref;
using ::absl::cordrep_testing::CordCollectRepsIf;
using ::absl::cordrep_testing::CordToString;
using ::absl::cordrep_testing::CordVisitReps;
using ::absl::cordrep_testing::CreateFlatsFromString;
using ::absl::cordrep_testing::CreateRandomString;
using ::absl::cordrep_testing::MakeExternal;
using ::absl::cordrep_testing::MakeFlat;
using ::absl::cordrep_testing::MakeSubstring;
using ::testing::_;
using ::testing::AllOf;
using ::testing::AnyOf;
using ::testing::Conditional;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::Le;
using ::testing::Ne;
using ::testing::Not;
using ::testing::SizeIs;
using ::testing::TypedEq;

MATCHER_P(EqFlatHolding, data, "Equals flat holding data") {
  if (arg->tag < FLAT) {
    *result_listener << "Expected FLAT, got tag " << static_cast<int>(arg->tag);
    return false;
  }
  std::string actual = CordToString(arg);
  if (actual != data) {
    *result_listener << "Expected flat holding \"" << data
                     << "\", got flat holding \"" << actual << "\"";
    return false;
  }
  return true;
}

MATCHER_P(IsNode, height, absl::StrCat("Is a valid node of height ", height)) {
  if (arg == nullptr) {
    *result_listener << "Expected NODE, got nullptr";
    return false;
  }
  if (arg->tag != BTREE) {
    *result_listener << "Expected NODE, got " << static_cast<int>(arg->tag);
    return false;
  }
  if (!CordRepBtree::IsValid(arg->btree())) {
    CordRepBtree::Dump(arg->btree(), "Expected valid NODE, got:", false,
                       *result_listener->stream());
    return false;
  }
  if (arg->btree()->height() != height) {
    *result_listener << "Expected NODE of height " << height << ", got "
                     << arg->btree()->height();
    return false;
  }
  return true;
}

MATCHER_P2(IsSubstring, start, length,
           absl::StrCat("Is a substring(start = ", start, ", length = ", length,
                        ")")) {
  if (arg == nullptr) {
    *result_listener << "Expected substring, got nullptr";
    return false;
  }
  if (arg->tag != SUBSTRING) {
    *result_listener << "Expected SUBSTRING, got "
                     << static_cast<int>(arg->tag);
    return false;
  }
  const CordRepSubstring* const substr = arg->substring();
  if (substr->start != start || substr->length != length) {
    *result_listener << "Expected substring(" << start << ", " << length
                     << "), got substring(" << substr->start << ", "
                     << substr->length << ")";
    return false;
  }
  return true;
}

MATCHER_P2(EqExtractResult, tree, rep, "Equals ExtractResult") {
  if (arg.tree != tree || arg.extracted != rep) {
    *result_listener << "Expected {" << static_cast<const void*>(tree) << ", "
                     << static_cast<const void*>(rep) << "}, got {" << arg.tree
                     << ", " << arg.extracted << "}";
    return false;
  }
  return true;
}

// DataConsumer is a simple helper class used by tests to 'consume' string
// fragments from the provided input in forward or backward direction.
class DataConsumer {
 public:
  // Starts consumption of `data`. Caller must make sure `data` outlives this
  // instance. Consumes data starting at the front if `forward` is true, else
  // consumes data from the back.
  DataConsumer(absl::string_view data, bool forward)
      : data_(data), forward_(forward) {}

  // Return the next `n` bytes from referenced data.
  absl::string_view Next(size_t n) {
    assert(n <= data_.size() - consumed_);
    consumed_ += n;
    return data_.substr(forward_ ? consumed_ - n : data_.size() - consumed_, n);
  }

  // Returns all data consumed so far.
  absl::string_view Consumed() const {
    return forward_ ? data_.substr(0, consumed_)
                    : data_.substr(data_.size() - consumed_);
  }

 private:
  absl::string_view data_;
  size_t consumed_ = 0;
  bool forward_;
};

// BtreeAdd returns either CordRepBtree::Append or CordRepBtree::Prepend.
CordRepBtree* BtreeAdd(CordRepBtree* node, bool append,
                       absl::string_view data) {
  return append ? CordRepBtree::Append(node, data)
                : CordRepBtree::Prepend(node, data);
}

// Recursively collects all leaf edges from `tree` and appends them to `edges`.
void GetLeafEdges(const CordRepBtree* tree, std::vector<CordRep*>& edges) {
  if (tree->height() == 0) {
    for (CordRep* edge : tree->Edges()) {
      edges.push_back(edge);
    }
  } else {
    for (CordRep* edge : tree->Edges()) {
      GetLeafEdges(edge->btree(), edges);
    }
  }
}

// Recursively collects and returns all leaf edges from `tree`.
std::vector<CordRep*> GetLeafEdges(const CordRepBtree* tree) {
  std::vector<CordRep*> edges;
  GetLeafEdges(tree, edges);
  return edges;
}

// Creates a flat containing the hexadecimal value of `i` zero padded
// to at least 4 digits prefixed with "0x", e.g.: "0x04AC".
CordRepFlat* MakeHexFlat(size_t i) {
  return MakeFlat(absl::StrCat("0x", absl::Hex(i, absl::kZeroPad4)));
}

CordRepBtree* MakeLeaf(size_t size = CordRepBtree::kMaxCapacity) {
  assert(size <= CordRepBtree::kMaxCapacity);
  CordRepBtree* leaf = CordRepBtree::Create(MakeHexFlat(0));
  for (size_t i = 1; i < size; ++i) {
    leaf = CordRepBtree::Append(leaf, MakeHexFlat(i));
  }
  return leaf;
}

CordRepBtree* MakeTree(size_t size, bool append = true) {
  CordRepBtree* tree = CordRepBtree::Create(MakeHexFlat(0));
  for (size_t i = 1; i < size; ++i) {
    tree = append ? CordRepBtree::Append(tree, MakeHexFlat(i))
                  : CordRepBtree::Prepend(tree, MakeHexFlat(i));
  }
  return tree;
}

CordRepBtree* CreateTree(absl::Span<CordRep* const> reps) {
  auto it = reps.begin();
  CordRepBtree* tree = CordRepBtree::Create(*it);
  while (++it != reps.end()) tree = CordRepBtree::Append(tree, *it);
  return tree;
}

CordRepBtree* CreateTree(absl::string_view data, size_t chunk_size) {
  return CreateTree(CreateFlatsFromString(data, chunk_size));
}

CordRepBtree* CreateTreeReverse(absl::string_view data, size_t chunk_size) {
  std::vector<CordRep*> flats = CreateFlatsFromString(data, chunk_size);
  auto rit = flats.rbegin();
  CordRepBtree* tree = CordRepBtree::Create(*rit);
  while (++rit != flats.rend()) tree = CordRepBtree::Prepend(tree, *rit);
  return tree;
}

class CordRepBtreeTest : public testing::TestWithParam<bool> {
 public:
  bool shared() const { return GetParam(); }

  static std::string ToString(testing::TestParamInfo<bool> param) {
    return param.param ? "Shared" : "Private";
  }
};

INSTANTIATE_TEST_SUITE_P(WithParam, CordRepBtreeTest, testing::Bool(),
                         CordRepBtreeTest::ToString);

class CordRepBtreeHeightTest : public testing::TestWithParam<int> {
 public:
  int height() const { return GetParam(); }

  static std::string ToString(testing::TestParamInfo<int> param) {
    return absl::StrCat(param.param);
  }
};

INSTANTIATE_TEST_SUITE_P(WithHeights, CordRepBtreeHeightTest,
                         testing::Range(0, CordRepBtree::kMaxHeight),
                         CordRepBtreeHeightTest::ToString);

using TwoBools = testing::tuple<bool, bool>;

class CordRepBtreeDualTest : public testing::TestWithParam<TwoBools> {
 public:
  bool first_shared() const { return std::get<0>(GetParam()); }
  bool second_shared() const { return std::get<1>(GetParam()); }

  static std::string ToString(testing::TestParamInfo<TwoBools> param) {
    if (std::get<0>(param.param)) {
      return std::get<1>(param.param) ? "BothShared" : "FirstShared";
    }
    return std::get<1>(param.param) ? "SecondShared" : "Private";
  }
};

INSTANTIATE_TEST_SUITE_P(WithParam, CordRepBtreeDualTest,
                         testing::Combine(testing::Bool(), testing::Bool()),
                         CordRepBtreeDualTest::ToString);

TEST(CordRepBtreeTest, SizeIsMultipleOf64) {
  // Only enforce for fully 64-bit platforms.
  if (sizeof(size_t) == 8 && sizeof(void*) == 8) {
    EXPECT_THAT(sizeof(CordRepBtree) % 64, Eq(0u))
        << "Should be multiple of 64";
  }
}

TEST(CordRepBtreeTest, NewDestroyEmptyTree) {
  auto* tree = CordRepBtree::New();
  EXPECT_THAT(tree->size(), Eq(0u));
  EXPECT_THAT(tree->height(), Eq(0));
  EXPECT_THAT(tree->Edges(), ElementsAre());
  CordRepBtree::Destroy(tree);
}

TEST(CordRepBtreeTest, NewDestroyEmptyTreeAtHeight) {
  auto* tree = CordRepBtree::New(3);
  EXPECT_THAT(tree->size(), Eq(0u));
  EXPECT_THAT(tree->height(), Eq(3));
  EXPECT_THAT(tree->Edges(), ElementsAre());
  CordRepBtree::Destroy(tree);
}

TEST(CordRepBtreeTest, Btree) {
  CordRep* rep = CordRepBtree::New();
  EXPECT_THAT(rep->btree(), Eq(rep));
  EXPECT_THAT(static_cast<const CordRep*>(rep)->btree(), Eq(rep));
  CordRep::Unref(rep);
#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
  rep = MakeFlat("Hello world");
  EXPECT_DEATH(rep->btree(), ".*");
  EXPECT_DEATH(static_cast<const CordRep*>(rep)->btree(), ".*");
  CordRep::Unref(rep);
#endif
}

TEST(CordRepBtreeTest, EdgeData) {
  CordRepFlat* flat = MakeFlat("Hello world");
  CordRepExternal* external = MakeExternal("Hello external");
  CordRep* substr1 = MakeSubstring(1, 6, CordRep::Ref(flat));
  CordRep* substr2 = MakeSubstring(1, 6, CordRep::Ref(external));
  CordRep* bad_substr = MakeSubstring(1, 2, CordRep::Ref(substr1));

  EXPECT_TRUE(IsDataEdge(flat));
  EXPECT_THAT(EdgeData(flat).data(), TypedEq<const void*>(flat->Data()));
  EXPECT_THAT(EdgeData(flat), Eq("Hello world"));

  EXPECT_TRUE(IsDataEdge(external));
  EXPECT_THAT(EdgeData(external).data(), TypedEq<const void*>(external->base));
  EXPECT_THAT(EdgeData(external), Eq("Hello external"));

  EXPECT_TRUE(IsDataEdge(substr1));
  EXPECT_THAT(EdgeData(substr1).data(), TypedEq<const void*>(flat->Data() + 1));
  EXPECT_THAT(EdgeData(substr1), Eq("ello w"));

  EXPECT_TRUE(IsDataEdge(substr2));
  EXPECT_THAT(EdgeData(substr2).data(),
              TypedEq<const void*>(external->base + 1));
  EXPECT_THAT(EdgeData(substr2), Eq("ello e"));

  EXPECT_FALSE(IsDataEdge(bad_substr));
#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
  EXPECT_DEATH(EdgeData(bad_substr), ".*");
#endif

  CordRep::Unref(bad_substr);
  CordRep::Unref(substr2);
  CordRep::Unref(substr1);
  CordRep::Unref(external);
  CordRep::Unref(flat);
}

TEST(CordRepBtreeTest, CreateUnrefLeaf) {
  auto* flat = MakeFlat("a");
  auto* leaf = CordRepBtree::Create(flat);
  EXPECT_THAT(leaf->size(), Eq(1u));
  EXPECT_THAT(leaf->height(), Eq(0));
  EXPECT_THAT(leaf->Edges(), ElementsAre(flat));
  CordRepBtree::Unref(leaf);
}

TEST(CordRepBtreeTest, NewUnrefNode) {
  auto* leaf = CordRepBtree::Create(MakeFlat("a"));
  CordRepBtree* tree = CordRepBtree::New(leaf);
  EXPECT_THAT(tree->size(), Eq(1u));
  EXPECT_THAT(tree->height(), Eq(1));
  EXPECT_THAT(tree->Edges(), ElementsAre(leaf));
  CordRepBtree::Unref(tree);
}

TEST_P(CordRepBtreeTest, AppendToLeafToCapacity) {
  AutoUnref refs;
  std::vector<CordRep*> flats;
  flats.push_back(MakeHexFlat(0));
  auto* leaf = CordRepBtree::Create(flats.back());

  for (size_t i = 1; i < CordRepBtree::kMaxCapacity; ++i) {
    refs.RefIf(shared(), leaf);
    flats.push_back(MakeHexFlat(i));
    auto* result = CordRepBtree::Append(leaf, flats.back());
    EXPECT_THAT(result->height(), Eq(0));
    EXPECT_THAT(result, Conditional(shared(), Ne(leaf), Eq(leaf)));
    EXPECT_THAT(result->Edges(), ElementsAreArray(flats));
    leaf = result;
  }
  CordRep::Unref(leaf);
}

TEST_P(CordRepBtreeTest, PrependToLeafToCapacity) {
  AutoUnref refs;
  std::deque<CordRep*> flats;
  flats.push_front(MakeHexFlat(0));
  auto* leaf = CordRepBtree::Create(flats.front());

  for (size_t i = 1; i < CordRepBtree::kMaxCapacity; ++i) {
    refs.RefIf(shared(), leaf);
    flats.push_front(MakeHexFlat(i));
    auto* result = CordRepBtree::Prepend(leaf, flats.front());
    EXPECT_THAT(result->height(), Eq(0));
    EXPECT_THAT(result, Conditional(shared(), Ne(leaf), Eq(leaf)));
    EXPECT_THAT(result->Edges(), ElementsAreArray(flats));
    leaf = result;
  }
  CordRep::Unref(leaf);
}

// This test specifically aims at code aligning data at either the front or the
// back of the contained `edges[]` array, alternating Append and Prepend will
// move `begin()` and `end()` values as needed for each added value.
TEST_P(CordRepBtreeTest, AppendPrependToLeafToCapacity) {
  AutoUnref refs;
  std::deque<CordRep*> flats;
  flats.push_front(MakeHexFlat(0));
  auto* leaf = CordRepBtree::Create(flats.front());

  for (size_t i = 1; i < CordRepBtree::kMaxCapacity; ++i) {
    refs.RefIf(shared(), leaf);
    CordRepBtree* result;
    if (i % 2 != 0) {
      flats.push_front(MakeHexFlat(i));
      result = CordRepBtree::Prepend(leaf, flats.front());
    } else {
      flats.push_back(MakeHexFlat(i));
      result = CordRepBtree::Append(leaf, flats.back());
    }
    EXPECT_THAT(result->height(), Eq(0));
    EXPECT_THAT(result, Conditional(shared(), Ne(leaf), Eq(leaf)));
    EXPECT_THAT(result->Edges(), ElementsAreArray(flats));
    leaf = result;
  }
  CordRep::Unref(leaf);
}

TEST_P(CordRepBtreeTest, AppendToLeafBeyondCapacity) {
  AutoUnref refs;
  auto* leaf = MakeLeaf();
  refs.RefIf(shared(), leaf);
  CordRep* flat = MakeFlat("abc");
  auto* result = CordRepBtree::Append(leaf, flat);
  ASSERT_THAT(result, IsNode(1));
  EXPECT_THAT(result, Ne(leaf));
  absl::Span<CordRep* const> edges = result->Edges();
  ASSERT_THAT(edges, ElementsAre(leaf, IsNode(0)));
  EXPECT_THAT(edges[1]->btree()->Edges(), ElementsAre(flat));
  CordRep::Unref(result);
}

TEST_P(CordRepBtreeTest, PrependToLeafBeyondCapacity) {
  AutoUnref refs;
  auto* leaf = MakeLeaf();
  refs.RefIf(shared(), leaf);
  CordRep* flat = MakeFlat("abc");
  auto* result = CordRepBtree::Prepend(leaf, flat);
  ASSERT_THAT(result, IsNode(1));
  EXPECT_THAT(result, Ne(leaf));
  absl::Span<CordRep* const> edges = result->Edges();
  ASSERT_THAT(edges, ElementsAre(IsNode(0), leaf));
  EXPECT_THAT(edges[0]->btree()->Edges(), ElementsAre(flat));
  CordRep::Unref(result);
}

TEST_P(CordRepBtreeTest, AppendToTreeOneDeep) {
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  AutoUnref refs;
  std::vector<CordRep*> flats;
  flats.push_back(MakeHexFlat(0));
  CordRepBtree* tree = CordRepBtree::Create(flats.back());
  for (size_t i = 1; i <= max_cap; ++i) {
    flats.push_back(MakeHexFlat(i));
    tree = CordRepBtree::Append(tree, flats.back());
  }
  ASSERT_THAT(tree, IsNode(1));

  for (size_t i = max_cap + 1; i < max_cap * max_cap; ++i) {
    // Ref top level tree based on param.
    // Ref leaf node once every 4 iterations, which should not have an
    // observable effect other than that the leaf itself is copied.
    refs.RefIf(shared(), tree);
    refs.RefIf(i % 4 == 0, tree->Edges().back());

    flats.push_back(MakeHexFlat(i));
    CordRepBtree* result = CordRepBtree::Append(tree, flats.back());
    ASSERT_THAT(result, IsNode(1));
    ASSERT_THAT(result, Conditional(shared(), Ne(tree), Eq(tree)));
    std::vector<CordRep*> edges = GetLeafEdges(result);
    ASSERT_THAT(edges, ElementsAreArray(flats));
    tree = result;
  }
  CordRep::Unref(tree);
}

TEST_P(CordRepBtreeTest, AppendToTreeTwoDeep) {
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  AutoUnref refs;
  std::vector<CordRep*> flats;
  flats.push_back(MakeHexFlat(0));
  CordRepBtree* tree = CordRepBtree::Create(flats.back());
  for (size_t i = 1; i <= max_cap * max_cap; ++i) {
    flats.push_back(MakeHexFlat(i));
    tree = CordRepBtree::Append(tree, flats.back());
  }
  ASSERT_THAT(tree, IsNode(2));
  for (size_t i = max_cap * max_cap + 1; i < max_cap * max_cap * max_cap; ++i) {
    // Ref top level tree based on param.
    // Ref child node once every 16 iterations, and leaf node every 4
    // iterrations which  which should not have an observable effect other than
    //  the node and/or the leaf below it being copied.
    refs.RefIf(shared(), tree);
    refs.RefIf(i % 16 == 0, tree->Edges().back());
    refs.RefIf(i % 4 == 0, tree->Edges().back()->btree()->Edges().back());

    flats.push_back(MakeHexFlat(i));
    CordRepBtree* result = CordRepBtree::Append(tree, flats.back());
    ASSERT_THAT(result, IsNode(2));
    ASSERT_THAT(result, Conditional(shared(), Ne(tree), Eq(tree)));
    std::vector<CordRep*> edges = GetLeafEdges(result);
    ASSERT_THAT(edges, ElementsAreArray(flats));
    tree = result;
  }
  CordRep::Unref(tree);
}

TEST_P(CordRepBtreeTest, PrependToTreeOneDeep) {
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  AutoUnref refs;
  std::deque<CordRep*> flats;
  flats.push_back(MakeHexFlat(0));
  CordRepBtree* tree = CordRepBtree::Create(flats.back());
  for (size_t i = 1; i <= max_cap; ++i) {
    flats.push_front(MakeHexFlat(i));
    tree = CordRepBtree::Prepend(tree, flats.front());
  }
  ASSERT_THAT(tree, IsNode(1));

  for (size_t i = max_cap + 1; i < max_cap * max_cap; ++i) {
    // Ref top level tree based on param.
    // Ref leaf node once every 4 iterations which should not have an observable
    // effect other than than the leaf itself is copied.
    refs.RefIf(shared(), tree);
    refs.RefIf(i % 4 == 0, tree->Edges().back());

    flats.push_front(MakeHexFlat(i));
    CordRepBtree* result = CordRepBtree::Prepend(tree, flats.front());
    ASSERT_THAT(result, IsNode(1));
    ASSERT_THAT(result, Conditional(shared(), Ne(tree), Eq(tree)));
    std::vector<CordRep*> edges = GetLeafEdges(result);
    ASSERT_THAT(edges, ElementsAreArray(flats));
    tree = result;
  }
  CordRep::Unref(tree);
}

TEST_P(CordRepBtreeTest, PrependToTreeTwoDeep) {
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  AutoUnref refs;
  std::deque<CordRep*> flats;
  flats.push_back(MakeHexFlat(0));
  CordRepBtree* tree = CordRepBtree::Create(flats.back());
  for (size_t i = 1; i <= max_cap * max_cap; ++i) {
    flats.push_front(MakeHexFlat(i));
    tree = CordRepBtree::Prepend(tree, flats.front());
  }
  ASSERT_THAT(tree, IsNode(2));
  for (size_t i = max_cap * max_cap + 1; i < max_cap * max_cap * max_cap; ++i) {
    // Ref top level tree based on param.
    // Ref child node once every 16 iterations, and leaf node every 4
    // iterrations which  which should not have an observable effect other than
    //  the node and/or the leaf below it being copied.
    refs.RefIf(shared(), tree);
    refs.RefIf(i % 16 == 0, tree->Edges().back());
    refs.RefIf(i % 4 == 0, tree->Edges().back()->btree()->Edges().back());

    flats.push_front(MakeHexFlat(i));
    CordRepBtree* result = CordRepBtree::Prepend(tree, flats.front());
    ASSERT_THAT(result, IsNode(2));
    ASSERT_THAT(result, Conditional(shared(), Ne(tree), Eq(tree)));
    std::vector<CordRep*> edges = GetLeafEdges(result);
    ASSERT_THAT(edges, ElementsAreArray(flats));
    tree = result;
  }
  CordRep::Unref(tree);
}

TEST_P(CordRepBtreeDualTest, MergeLeafsNotExceedingCapacity) {
  for (bool use_append : {false, true}) {
    SCOPED_TRACE(use_append ? "Using Append" : "Using Prepend");

    AutoUnref refs;
    std::vector<CordRep*> flats;

    // Build `left` side leaf appending all contained flats to `flats`
    CordRepBtree* left = MakeLeaf(3);
    GetLeafEdges(left, flats);
    refs.RefIf(first_shared(), left);

    // Build `right` side leaf appending all contained flats to `flats`
    CordRepBtree* right = MakeLeaf(2);
    GetLeafEdges(right, flats);
    refs.RefIf(second_shared(), right);

    CordRepBtree* tree = use_append ? CordRepBtree::Append(left, right)
                                    : CordRepBtree::Prepend(right, left);
    EXPECT_THAT(tree, IsNode(0));

    // `tree` contains all flats originally belonging to `left` and `right`.
    EXPECT_THAT(tree->Edges(), ElementsAreArray(flats));
    CordRepBtree::Unref(tree);
  }
}

TEST_P(CordRepBtreeDualTest, MergeLeafsExceedingCapacity) {
  for (bool use_append : {false, true}) {
    SCOPED_TRACE(use_append ? "Using Append" : "Using Prepend");

    AutoUnref refs;

    // Build `left` side tree appending all contained flats to `flats`
    CordRepBtree* left = MakeLeaf(CordRepBtree::kMaxCapacity - 2);
    refs.RefIf(first_shared(), left);

    // Build `right` side tree appending all contained flats to `flats`
    CordRepBtree* right = MakeLeaf(CordRepBtree::kMaxCapacity - 1);
    refs.RefIf(second_shared(), right);

    CordRepBtree* tree = use_append ? CordRepBtree::Append(left, right)
                                    : CordRepBtree::Prepend(right, left);
    EXPECT_THAT(tree, IsNode(1));
    EXPECT_THAT(tree->Edges(), ElementsAre(left, right));
    CordRepBtree::Unref(tree);
  }
}

TEST_P(CordRepBtreeDualTest, MergeEqualHeightTrees) {
  for (bool use_append : {false, true}) {
    SCOPED_TRACE(use_append ? "Using Append" : "Using Prepend");

    AutoUnref refs;
    std::vector<CordRep*> flats;

    // Build `left` side tree appending all contained flats to `flats`
    CordRepBtree* left = MakeTree(CordRepBtree::kMaxCapacity * 3);
    GetLeafEdges(left, flats);
    refs.RefIf(first_shared(), left);

    // Build `right` side tree appending all contained flats to `flats`
    CordRepBtree* right = MakeTree(CordRepBtree::kMaxCapacity * 2);
    GetLeafEdges(right, flats);
    refs.RefIf(second_shared(), right);

    CordRepBtree* tree = use_append ? CordRepBtree::Append(left, right)
                                    : CordRepBtree::Prepend(right, left);
    EXPECT_THAT(tree, IsNode(1));
    EXPECT_THAT(tree->Edges(), SizeIs(5u));

    // `tree` contains all flats originally belonging to `left` and `right`.
    EXPECT_THAT(GetLeafEdges(tree), ElementsAreArray(flats));
    CordRepBtree::Unref(tree);
  }
}

TEST_P(CordRepBtreeDualTest, MergeLeafWithTreeNotExceedingLeafCapacity) {
  for (bool use_append : {false, true}) {
    SCOPED_TRACE(use_append ? "Using Append" : "Using Prepend");

    AutoUnref refs;
    std::vector<CordRep*> flats;

    // Build `left` side tree appending all added flats to `flats`
    CordRepBtree* left = MakeTree(CordRepBtree::kMaxCapacity * 2 + 2);
    GetLeafEdges(left, flats);
    refs.RefIf(first_shared(), left);

    // Build `right` side tree appending all added flats to `flats`
    CordRepBtree* right = MakeTree(3);
    GetLeafEdges(right, flats);
    refs.RefIf(second_shared(), right);

    CordRepBtree* tree = use_append ? CordRepBtree::Append(left, right)
                                    : CordRepBtree::Prepend(right, left);
    EXPECT_THAT(tree, IsNode(1));
    EXPECT_THAT(tree->Edges(), SizeIs(3u));

    // `tree` contains all flats originally belonging to `left` and `right`.
    EXPECT_THAT(GetLeafEdges(tree), ElementsAreArray(flats));
    CordRepBtree::Unref(tree);
  }
}

TEST_P(CordRepBtreeDualTest, MergeLeafWithTreeExceedingLeafCapacity) {
  for (bool use_append : {false, true}) {
    SCOPED_TRACE(use_append ? "Using Append" : "Using Prepend");

    AutoUnref refs;
    std::vector<CordRep*> flats;

    // Build `left` side tree appending all added flats to `flats`
    CordRepBtree* left = MakeTree(CordRepBtree::kMaxCapacity * 3 - 2);
    GetLeafEdges(left, flats);
    refs.RefIf(first_shared(), left);

    // Build `right` side tree appending all added flats to `flats`
    CordRepBtree* right = MakeTree(3);
    GetLeafEdges(right, flats);
    refs.RefIf(second_shared(), right);

    CordRepBtree* tree = use_append ? CordRepBtree::Append(left, right)
                                    : CordRepBtree::Prepend(right, left);
    EXPECT_THAT(tree, IsNode(1));
    EXPECT_THAT(tree->Edges(), SizeIs(4u));

    // `tree` contains all flats originally belonging to `left` and `right`.
    EXPECT_THAT(GetLeafEdges(tree), ElementsAreArray(flats));
    CordRepBtree::Unref(tree);
  }
}

void RefEdgesAt(size_t depth, AutoUnref& refs, CordRepBtree* tree) {
  absl::Span<CordRep* const> edges = tree->Edges();
  if (depth == 0) {
    refs.Ref(edges.front());
    refs.Ref(edges.back());
  } else {
    assert(tree->height() > 0);
    RefEdgesAt(depth - 1, refs, edges.front()->btree());
    RefEdgesAt(depth - 1, refs, edges.back()->btree());
  }
}

TEST(CordRepBtreeTest, MergeFuzzTest) {
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  std::minstd_rand rnd;
  std::uniform_int_distribution<int> coin_flip(0, 1);
  std::uniform_int_distribution<int> dice_throw(1, 6);

  auto random_leaf_count = [&]() {
    std::uniform_int_distribution<int> dist_height(0, 3);
    std::uniform_int_distribution<int> dist_leaf(0, max_cap - 1);
    const int height = dist_height(rnd);
    return (height ? pow(max_cap, height) : 0) + dist_leaf(rnd);
  };

  for (int i = 0; i < 10000; ++i) {
    AutoUnref refs;
    std::vector<CordRep*> flats;

    CordRepBtree* left = MakeTree(random_leaf_count(), coin_flip(rnd));
    GetLeafEdges(left, flats);
    if (dice_throw(rnd) == 1) {
      std::uniform_int_distribution<size_t> dist(
          0, static_cast<size_t>(left->height()));
      RefEdgesAt(dist(rnd), refs, left);
    }

    CordRepBtree* right = MakeTree(random_leaf_count(), coin_flip(rnd));
    GetLeafEdges(right, flats);
    if (dice_throw(rnd) == 1) {
      std::uniform_int_distribution<size_t> dist(
          0, static_cast<size_t>(right->height()));
      RefEdgesAt(dist(rnd), refs, right);
    }

    CordRepBtree* tree = CordRepBtree::Append(left, right);
    EXPECT_THAT(GetLeafEdges(tree), ElementsAreArray(flats));
    CordRepBtree::Unref(tree);
  }
}

TEST_P(CordRepBtreeTest, RemoveSuffix) {
  // Create tree of 1, 2 and 3 levels high
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  for (size_t cap : {max_cap - 1, max_cap * 2, max_cap * max_cap * 2}) {
    const std::string data = CreateRandomString(cap * 512);

    {
      // Verify RemoveSuffix(<all>)
      AutoUnref refs;
      CordRepBtree* node = refs.RefIf(shared(), CreateTree(data, 512));
      EXPECT_THAT(CordRepBtree::RemoveSuffix(node, data.length()), Eq(nullptr));

      // Verify RemoveSuffix(<none>)
      node = refs.RefIf(shared(), CreateTree(data, 512));
      EXPECT_THAT(CordRepBtree::RemoveSuffix(node, 0), Eq(node));
      CordRep::Unref(node);
    }

    for (size_t n = 1; n < data.length(); ++n) {
      AutoUnref refs;
      auto flats = CreateFlatsFromString(data, 512);
      CordRepBtree* node = refs.RefIf(shared(), CreateTree(flats));
      CordRep* rep = refs.Add(CordRepBtree::RemoveSuffix(node, n));
      EXPECT_THAT(CordToString(rep), Eq(data.substr(0, data.length() - n)));

      // Collect all flats
      auto is_flat = [](CordRep* rep) { return rep->tag >= FLAT; };
      std::vector<CordRep*> edges = CordCollectRepsIf(is_flat, rep);
      ASSERT_THAT(edges.size(), Le(flats.size()));

      // Isolate last edge
      CordRep* last_edge = edges.back();
      edges.pop_back();
      const size_t last_length = rep->length - edges.size() * 512;

      // All flats except the last edge must be kept or copied 'as is'
      size_t index = 0;
      for (CordRep* edge : edges) {
        ASSERT_THAT(edge, Eq(flats[index++]));
        ASSERT_THAT(edge->length, Eq(512u));
      }

      // CordRepBtree may optimize small substrings to avoid waste, so only
      // check for flat sharing / updates where the code should always do this.
      if (last_length >= 500) {
        EXPECT_THAT(last_edge, Eq(flats[index++]));
        if (shared()) {
          EXPECT_THAT(last_edge->length, Eq(512u));
        } else {
          EXPECT_TRUE(last_edge->refcount.IsOne());
          EXPECT_THAT(last_edge->length, Eq(last_length));
        }
      }
    }
  }
}

TEST(CordRepBtreeTest, SubTree) {
  // Create tree of at least 2 levels high
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  const size_t n = max_cap * max_cap * 2;
  const std::string data = CreateRandomString(n * 3);
  std::vector<CordRep*> flats;
  for (absl::string_view s = data; !s.empty(); s.remove_prefix(3)) {
    flats.push_back(MakeFlat(s.substr(0, 3)));
  }
  CordRepBtree* node = CordRepBtree::Create(CordRep::Ref(flats[0]));
  for (size_t i = 1; i < flats.size(); ++i) {
    node = CordRepBtree::Append(node, CordRep::Ref(flats[i]));
  }

  for (size_t offset = 0; offset < data.length(); ++offset) {
    for (size_t length = 1; length <= data.length() - offset; ++length) {
      CordRep* rep = node->SubTree(offset, length);
      EXPECT_THAT(CordToString(rep), Eq(data.substr(offset, length)));
      CordRep::Unref(rep);
    }
  }
  CordRepBtree::Unref(node);
  for (CordRep* rep : flats) {
    CordRep::Unref(rep);
  }
}

TEST(CordRepBtreeTest, SubTreeOnExistingSubstring) {
  // This test verifies that a SubTree call on a pre-existing (large) substring
  // adjusts the existing substring if not shared, and else rewrites the
  // existing substring.
  AutoUnref refs;
  std::string data = CreateRandomString(1000);
  CordRepBtree* leaf = CordRepBtree::Create(MakeFlat("abc"));
  CordRep* flat = MakeFlat(data);
  leaf = CordRepBtree::Append(leaf, flat);

  // Setup tree containing substring.
  CordRep* result = leaf->SubTree(0, 3 + 990);
  ASSERT_THAT(result->tag, Eq(BTREE));
  CordRep::Unref(leaf);
  leaf = result->btree();
  ASSERT_THAT(leaf->Edges(), ElementsAre(_, IsSubstring(0u, 990u)));
  EXPECT_THAT(leaf->Edges()[1]->substring()->child, Eq(flat));

  // Verify substring of substring.
  result = leaf->SubTree(3 + 5, 970);
  ASSERT_THAT(result, IsSubstring(5u, 970u));
  EXPECT_THAT(result->substring()->child, Eq(flat));
  CordRep::Unref(result);

  CordRep::Unref(leaf);
}

TEST_P(CordRepBtreeTest, AddDataToLeaf) {
  const size_t n = CordRepBtree::kMaxCapacity;
  const std::string data = CreateRandomString(n * 3);

  for (bool append : {true, false}) {
    AutoUnref refs;
    DataConsumer consumer(data, append);
    SCOPED_TRACE(append ? "Append" : "Prepend");

    CordRepBtree* leaf = CordRepBtree::Create(MakeFlat(consumer.Next(3)));
    for (size_t i = 1; i < n; ++i) {
      refs.RefIf(shared(), leaf);
      CordRepBtree* result = BtreeAdd(leaf, append, consumer.Next(3));
      EXPECT_THAT(result, Conditional(shared(), Ne(leaf), Eq(leaf)));
      EXPECT_THAT(CordToString(result), Eq(consumer.Consumed()));
      leaf = result;
    }
    CordRep::Unref(leaf);
  }
}

TEST_P(CordRepBtreeTest, AppendDataToTree) {
  AutoUnref refs;
  size_t n = CordRepBtree::kMaxCapacity + CordRepBtree::kMaxCapacity / 2;
  std::string data = CreateRandomString(n * 3);
  CordRepBtree* tree = refs.RefIf(shared(), CreateTree(data, 3));
  CordRepBtree* leaf0 = tree->Edges()[0]->btree();
  CordRepBtree* leaf1 = tree->Edges()[1]->btree();
  CordRepBtree* result = CordRepBtree::Append(tree, "123456789");
  EXPECT_THAT(result, Conditional(shared(), Ne(tree), Eq(tree)));
  EXPECT_THAT(result->Edges(),
              ElementsAre(leaf0, Conditional(shared(), Ne(leaf1), Eq(leaf1))));
  EXPECT_THAT(CordToString(result), Eq(data + "123456789"));
  CordRep::Unref(result);
}

TEST_P(CordRepBtreeTest, PrependDataToTree) {
  AutoUnref refs;
  size_t n = CordRepBtree::kMaxCapacity + CordRepBtree::kMaxCapacity / 2;
  std::string data = CreateRandomString(n * 3);
  CordRepBtree* tree = refs.RefIf(shared(), CreateTreeReverse(data, 3));
  CordRepBtree* leaf0 = tree->Edges()[0]->btree();
  CordRepBtree* leaf1 = tree->Edges()[1]->btree();
  CordRepBtree* result = CordRepBtree::Prepend(tree, "123456789");
  EXPECT_THAT(result, Conditional(shared(), Ne(tree), Eq(tree)));
  EXPECT_THAT(result->Edges(),
              ElementsAre(Conditional(shared(), Ne(leaf0), Eq(leaf0)), leaf1));
  EXPECT_THAT(CordToString(result), Eq("123456789" + data));
  CordRep::Unref(result);
}

TEST_P(CordRepBtreeTest, AddDataToTreeThreeLevelsDeep) {
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  const size_t n = max_cap * max_cap * max_cap;
  const std::string data = CreateRandomString(n * 3);

  for (bool append : {true, false}) {
    AutoUnref refs;
    DataConsumer consumer(data, append);
    SCOPED_TRACE(append ? "Append" : "Prepend");

    // Fill leaf
    CordRepBtree* tree = CordRepBtree::Create(MakeFlat(consumer.Next(3)));
    for (size_t i = 1; i < max_cap; ++i) {
      tree = BtreeAdd(tree, append, consumer.Next(3));
    }
    ASSERT_THAT(CordToString(tree), Eq(consumer.Consumed()));

    // Fill to maximum at one deep
    refs.RefIf(shared(), tree);
    CordRepBtree* result = BtreeAdd(tree, append, consumer.Next(3));
    ASSERT_THAT(result, IsNode(1));
    ASSERT_THAT(result, Ne(tree));
    ASSERT_THAT(CordToString(result), Eq(consumer.Consumed()));
    tree = result;
    for (size_t i = max_cap + 1; i < max_cap * max_cap; ++i) {
      refs.RefIf(shared(), tree);
      result = BtreeAdd(tree, append, consumer.Next(3));
      ASSERT_THAT(result, Conditional(shared(), Ne(tree), Eq(tree)));
      ASSERT_THAT(CordToString(result), Eq(consumer.Consumed()));
      tree = result;
    }

    // Fill to maximum at two deep
    refs.RefIf(shared(), tree);
    result = BtreeAdd(tree, append, consumer.Next(3));
    ASSERT_THAT(result, IsNode(2));
    ASSERT_THAT(result, Ne(tree));
    ASSERT_THAT(CordToString(result), Eq(consumer.Consumed()));
    tree = result;
    for (size_t i = max_cap * max_cap + 1; i < max_cap * max_cap * max_cap;
         ++i) {
      refs.RefIf(shared(), tree);
      result = BtreeAdd(tree, append, consumer.Next(3));
      ASSERT_THAT(result, Conditional(shared(), Ne(tree), Eq(tree)));
      ASSERT_THAT(CordToString(result), Eq(consumer.Consumed()));
      tree = result;
    }

    CordRep::Unref(tree);
  }
}

TEST_P(CordRepBtreeTest, AddLargeDataToLeaf) {
  const size_t max_cap = CordRepBtree::kMaxCapacity;
  const size_t n = max_cap * max_cap * max_cap * 3 + 2;
  const std::string data = CreateRandomString(n * kMaxFlatLength);

  for (bool append : {true, false}) {
    AutoUnref refs;
    SCOPED_TRACE(append ? "Append" : "Prepend");

    CordRepBtree* leaf = CordRepBtree::Create(MakeFlat("abc"));
    refs.RefIf(shared(), leaf);
    CordRepBtree* result = BtreeAdd(leaf, append, data);
    EXPECT_THAT(CordToString(result), Eq(append ? "abc" + data : data + "abc"));
    CordRep::Unref(result);
  }
}

TEST_P(CordRepBtreeTest, CreateFromTreeReturnsTree) {
  AutoUnref refs;
  CordRepBtree* leaf = CordRepBtree::Create(MakeFlat("Hello world"));
  refs.RefIf(shared(), leaf);
  CordRepBtree* result = CordRepBtree::Create(leaf);
  EXPECT_THAT(result, Eq(leaf));
  CordRep::Unref(result);
}

TEST(CordRepBtreeTest, GetCharacter) {
  size_t n = CordRepBtree::kMaxCapacity * CordRepBtree::kMaxCapacity + 2;
  std::string data = CreateRandomString(n * 3);
  CordRepBtree* tree = CreateTree(data, 3);
  // Add a substring node for good measure.
  tree = tree->Append(tree, MakeSubstring(4, 5, MakeFlat("abcdefghijklm")));
  data += "efghi";
  for (size_t i = 0; i < data.length(); ++i) {
    ASSERT_THAT(tree->GetCharacter(i), Eq(data[i]));
  }
  CordRep::Unref(tree);
}

TEST_P(CordRepBtreeTest, IsFlatSingleFlat) {
  CordRepBtree* leaf = CordRepBtree::Create(MakeFlat("Hello world"));

  absl::string_view fragment;
  EXPECT_TRUE(leaf->IsFlat(nullptr));
  EXPECT_TRUE(leaf->IsFlat(&fragment));
  EXPECT_THAT(fragment, Eq("Hello world"));
  fragment = "";
  EXPECT_TRUE(leaf->IsFlat(0, 11, nullptr));
  EXPECT_TRUE(leaf->IsFlat(0, 11, &fragment));
  EXPECT_THAT(fragment, Eq("Hello world"));

  // Arbitrary ranges must check true as well.
  EXPECT_TRUE(leaf->IsFlat(1, 4, &fragment));
  EXPECT_THAT(fragment, Eq("ello"));
  EXPECT_TRUE(leaf->IsFlat(6, 5, &fragment));
  EXPECT_THAT(fragment, Eq("world"));

  CordRep::Unref(leaf);
}

TEST(CordRepBtreeTest, IsFlatMultiFlat) {
  size_t n = CordRepBtree::kMaxCapacity * CordRepBtree::kMaxCapacity + 2;
  std::string data = CreateRandomString(n * 3);
  CordRepBtree* tree = CreateTree(data, 3);
  // Add substring nodes for good measure.
  tree = tree->Append(tree, MakeSubstring(4, 3, MakeFlat("abcdefghijklm")));
  tree = tree->Append(tree, MakeSubstring(8, 3, MakeFlat("abcdefghijklm")));
  data += "efgijk";

  EXPECT_FALSE(tree->IsFlat(nullptr));
  absl::string_view fragment = "Can't touch this";
  EXPECT_FALSE(tree->IsFlat(&fragment));
  EXPECT_THAT(fragment, Eq("Can't touch this"));

  for (size_t offset = 0; offset < data.size(); offset += 3) {
    EXPECT_TRUE(tree->IsFlat(offset, 3, nullptr));
    EXPECT_TRUE(tree->IsFlat(offset, 3, &fragment));
    EXPECT_THAT(fragment, Eq(data.substr(offset, 3)));

    fragment = "Can't touch this";
    if (offset > 0) {
      EXPECT_FALSE(tree->IsFlat(offset - 1, 4, nullptr));
      EXPECT_FALSE(tree->IsFlat(offset - 1, 4, &fragment));
      EXPECT_THAT(fragment, Eq("Can't touch this"));
    }
    if (offset < data.size() - 4) {
      EXPECT_FALSE(tree->IsFlat(offset, 4, nullptr));
      EXPECT_FALSE(tree->IsFlat(offset, 4, &fragment));
      EXPECT_THAT(fragment, Eq("Can't touch this"));
    }
  }

  CordRep::Unref(tree);
}

#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)

TEST_P(CordRepBtreeHeightTest, GetAppendBufferNotPrivate) {
  CordRepBtree* tree = CordRepBtree::Create(MakeExternal("Foo"));
  CordRepBtree::Ref(tree);
  EXPECT_DEATH(tree->GetAppendBuffer(1), ".*");
  CordRepBtree::Unref(tree);
  CordRepBtree::Unref(tree);
}

#endif  // defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)

TEST_P(CordRepBtreeHeightTest, GetAppendBufferNotFlat) {
  CordRepBtree* tree = CordRepBtree::Create(MakeExternal("Foo"));
  for (int i = 1; i <= height(); ++i) {
    tree = CordRepBtree::New(tree);
  }
  EXPECT_THAT(tree->GetAppendBuffer(1), SizeIs(0u));
  CordRepBtree::Unref(tree);
}

TEST_P(CordRepBtreeHeightTest, GetAppendBufferFlatNotPrivate) {
  CordRepFlat* flat = MakeFlat("abc");
  CordRepBtree* tree = CordRepBtree::Create(CordRep::Ref(flat));
  for (int i = 1; i <= height(); ++i) {
    tree = CordRepBtree::New(tree);
  }
  EXPECT_THAT(tree->GetAppendBuffer(1), SizeIs(0u));
  CordRepBtree::Unref(tree);
  CordRep::Unref(flat);
}

TEST_P(CordRepBtreeHeightTest, GetAppendBufferTreeNotPrivate) {
  if (height() == 0) return;
  AutoUnref refs;
  CordRepFlat* flat = MakeFlat("abc");
  CordRepBtree* tree = CordRepBtree::Create(CordRep::Ref(flat));
  for (int i = 1; i <= height(); ++i) {
    if (i == (height() + 1) / 2) refs.Ref(tree);
    tree = CordRepBtree::New(tree);
  }
  EXPECT_THAT(tree->GetAppendBuffer(1), SizeIs(0u));
  CordRepBtree::Unref(tree);
  CordRep::Unref(flat);
}

TEST_P(CordRepBtreeHeightTest, GetAppendBufferFlatNoCapacity) {
  CordRepFlat* flat = MakeFlat("abc");
  flat->length = flat->Capacity();
  CordRepBtree* tree = CordRepBtree::Create(flat);
  for (int i = 1; i <= height(); ++i) {
    tree = CordRepBtree::New(tree);
  }
  EXPECT_THAT(tree->GetAppendBuffer(1), SizeIs(0u));
  CordRepBtree::Unref(tree);
}

TEST_P(CordRepBtreeHeightTest, GetAppendBufferFlatWithCapacity) {
  CordRepFlat* flat = MakeFlat("abc");
  CordRepBtree* tree = CordRepBtree::Create(flat);
  for (int i = 1; i <= height(); ++i) {
    tree = CordRepBtree::New(tree);
  }
  absl::Span<char> span = tree->GetAppendBuffer(2);
  EXPECT_THAT(span, SizeIs(2u));
  EXPECT_THAT(span.data(), TypedEq<void*>(flat->Data() + 3));
  EXPECT_THAT(tree->length, Eq(5u));

  size_t avail = flat->Capacity() - 5;
  span = tree->GetAppendBuffer(avail + 100);
  EXPECT_THAT(span, SizeIs(avail));
  EXPECT_THAT(span.data(), TypedEq<void*>(flat->Data() + 5));
  EXPECT_THAT(tree->length, Eq(5 + avail));

  CordRepBtree::Unref(tree);
}

TEST(CordRepBtreeTest, Dump) {
  // Handles nullptr
  std::stringstream ss;
  CordRepBtree::Dump(nullptr, ss);
  CordRepBtree::Dump(nullptr, "Once upon a label", ss);
  CordRepBtree::Dump(nullptr, "Once upon a label", false, ss);
  CordRepBtree::Dump(nullptr, "Once upon a label", true, ss);

  // Cover legal edges
  CordRepFlat* flat = MakeFlat("Hello world");
  CordRepExternal* external = MakeExternal("Hello external");
  CordRep* substr_flat = MakeSubstring(1, 6, CordRep::Ref(flat));
  CordRep* substr_external = MakeSubstring(2, 7, CordRep::Ref(external));

  // Build tree
  CordRepBtree* tree = CordRepBtree::Create(flat);
  tree = CordRepBtree::Append(tree, external);
  tree = CordRepBtree::Append(tree, substr_flat);
  tree = CordRepBtree::Append(tree, substr_external);

  // Repeat until we have a tree
  while (tree->height() == 0) {
    tree = CordRepBtree::Append(tree, CordRep::Ref(flat));
    tree = CordRepBtree::Append(tree, CordRep::Ref(external));
    tree = CordRepBtree::Append(tree, CordRep::Ref(substr_flat));
    tree = CordRepBtree::Append(tree, CordRep::Ref(substr_external));
  }

  for (int api = 0; api <= 3; ++api) {
    absl::string_view api_scope;
    std::stringstream ss;
    switch (api) {
      case 0:
        api_scope = "Bare";
        CordRepBtree::Dump(tree, ss);
        break;
      case 1:
        api_scope = "Label only";
        CordRepBtree::Dump(tree, "Once upon a label", ss);
        break;
      case 2:
        api_scope = "Label no content";
        CordRepBtree::Dump(tree, "Once upon a label", false, ss);
        break;
      default:
        api_scope = "Label and content";
        CordRepBtree::Dump(tree, "Once upon a label", true, ss);
        break;
    }
    SCOPED_TRACE(api_scope);
    std::string str = ss.str();

    // Contains Node(depth) / Leaf and private / shared indicators
    EXPECT_THAT(str, AllOf(HasSubstr("Node(1)"), HasSubstr("Leaf"),
                           HasSubstr("Private"), HasSubstr("Shared")));

    // Contains length and start offset of all data edges
    EXPECT_THAT(str, AllOf(HasSubstr("len = 11"), HasSubstr("len = 14"),
                           HasSubstr("len = 6"), HasSubstr("len = 7"),
                           HasSubstr("start = 1"), HasSubstr("start = 2")));

    // Contains address of all data edges
    EXPECT_THAT(
        str, AllOf(HasSubstr(absl::StrCat("0x", absl::Hex(flat))),
                   HasSubstr(absl::StrCat("0x", absl::Hex(external))),
                   HasSubstr(absl::StrCat("0x", absl::Hex(substr_flat))),
                   HasSubstr(absl::StrCat("0x", absl::Hex(substr_external)))));

    if (api != 0) {
      // Contains label
      EXPECT_THAT(str, HasSubstr("Once upon a label"));
    }

    if (api != 3) {
      // Does not contain contents
      EXPECT_THAT(str, Not(AnyOf((HasSubstr("data = \"Hello world\""),
                                  HasSubstr("data = \"Hello external\""),
                                  HasSubstr("data = \"ello w\""),
                                  HasSubstr("data = \"llo ext\"")))));
    } else {
      // Contains contents
      EXPECT_THAT(str, AllOf((HasSubstr("data = \"Hello world\""),
                              HasSubstr("data = \"Hello external\""),
                              HasSubstr("data = \"ello w\""),
                              HasSubstr("data = \"llo ext\""))));
    }
  }

  CordRep::Unref(tree);
}

TEST(CordRepBtreeTest, IsValid) {
  EXPECT_FALSE(CordRepBtree::IsValid(nullptr));

  CordRepBtree* empty = CordRepBtree::New(0);
  EXPECT_TRUE(CordRepBtree::IsValid(empty));
  CordRep::Unref(empty);

  for (bool as_tree : {false, true}) {
    CordRepBtree* leaf = CordRepBtree::Create(MakeFlat("abc"));
    CordRepBtree* tree = as_tree ? CordRepBtree::New(leaf) : nullptr;
    CordRepBtree* check = as_tree ? tree : leaf;

    ASSERT_TRUE(CordRepBtree::IsValid(check));
    leaf->length--;
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    leaf->length++;

    ASSERT_TRUE(CordRepBtree::IsValid(check));
    leaf->tag--;
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    leaf->tag++;

    // Height
    ASSERT_TRUE(CordRepBtree::IsValid(check));
    leaf->storage[0] = static_cast<uint8_t>(CordRepBtree::kMaxHeight + 1);
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    leaf->storage[0] = 1;
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    leaf->storage[0] = 0;

    // Begin
    ASSERT_TRUE(CordRepBtree::IsValid(check));
    const uint8_t begin = leaf->storage[1];
    leaf->storage[1] = static_cast<uint8_t>(CordRepBtree::kMaxCapacity);
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    leaf->storage[1] = 2;
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    leaf->storage[1] = begin;

    // End
    ASSERT_TRUE(CordRepBtree::IsValid(check));
    const uint8_t end = leaf->storage[2];
    leaf->storage[2] = static_cast<uint8_t>(CordRepBtree::kMaxCapacity + 1);
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    leaf->storage[2] = end;

    // DataEdge tag and value
    ASSERT_TRUE(CordRepBtree::IsValid(check));
    CordRep* const edge = leaf->Edges()[0];
    const uint8_t tag = edge->tag;
    CordRepBtreeTestPeer::SetEdge(leaf, begin, nullptr);
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    CordRepBtreeTestPeer::SetEdge(leaf, begin, edge);
    edge->tag = BTREE;
    EXPECT_FALSE(CordRepBtree::IsValid(check));
    edge->tag = tag;

    if (as_tree) {
      ASSERT_TRUE(CordRepBtree::IsValid(check));
      leaf->length--;
      EXPECT_FALSE(CordRepBtree::IsValid(check));
      leaf->length++;

      // Height
      ASSERT_TRUE(CordRepBtree::IsValid(check));
      tree->storage[0] = static_cast<uint8_t>(2);
      EXPECT_FALSE(CordRepBtree::IsValid(check));
      tree->storage[0] = 1;

      // Btree edge
      ASSERT_TRUE(CordRepBtree::IsValid(check));
      CordRep* const edge = tree->Edges()[0];
      const uint8_t tag = edge->tag;
      edge->tag = FLAT;
      EXPECT_FALSE(CordRepBtree::IsValid(check));
      edge->tag = tag;
    }

    ASSERT_TRUE(CordRepBtree::IsValid(check));
    CordRep::Unref(check);
  }
}

TEST(CordRepBtreeTest, AssertValid) {
  CordRepBtree* tree = CordRepBtree::Create(MakeFlat("abc"));
  const CordRepBtree* ctree = tree;
  EXPECT_THAT(CordRepBtree::AssertValid(tree), Eq(tree));
  EXPECT_THAT(CordRepBtree::AssertValid(ctree), Eq(ctree));

#if defined(GTEST_HAS_DEATH_TEST)
  CordRepBtree* nulltree = nullptr;
  const CordRepBtree* cnulltree = nullptr;
  EXPECT_DEBUG_DEATH(
      EXPECT_THAT(CordRepBtree::AssertValid(nulltree), Eq(nulltree)), ".*");
  EXPECT_DEBUG_DEATH(
      EXPECT_THAT(CordRepBtree::AssertValid(cnulltree), Eq(cnulltree)), ".*");

  tree->length--;
  EXPECT_DEBUG_DEATH(EXPECT_THAT(CordRepBtree::AssertValid(tree), Eq(tree)),
                     ".*");
  EXPECT_DEBUG_DEATH(EXPECT_THAT(CordRepBtree::AssertValid(ctree), Eq(ctree)),
                     ".*");
  tree->length++;
#endif
  CordRep::Unref(tree);
}

TEST(CordRepBtreeTest, CheckAssertValidShallowVsDeep) {
  // Restore exhaustive validation on any exit.
  const bool exhaustive_validation = cord_btree_exhaustive_validation.load();
  auto cleanup = absl::MakeCleanup([exhaustive_validation] {
    cord_btree_exhaustive_validation.store(exhaustive_validation);
  });

  // Create a tree of at least 2 levels, and mess with the original flat, which
  // should go undetected in shallow mode as the flat is too far away, but
  // should be detected in forced non-shallow mode.
  CordRep* flat = MakeFlat("abc");
  CordRepBtree* tree = CordRepBtree::Create(flat);
  constexpr size_t max_cap = CordRepBtree::kMaxCapacity;
  const size_t n = max_cap * max_cap * 2;
  for (size_t i = 0; i < n; ++i) {
    tree = CordRepBtree::Append(tree, MakeFlat("Hello world"));
  }
  flat->length = 100;

  cord_btree_exhaustive_validation.store(false);
  EXPECT_FALSE(CordRepBtree::IsValid(tree));
  EXPECT_TRUE(CordRepBtree::IsValid(tree, true));
  EXPECT_FALSE(CordRepBtree::IsValid(tree, false));
  CordRepBtree::AssertValid(tree);
  CordRepBtree::AssertValid(tree, true);
#if defined(GTEST_HAS_DEATH_TEST)
  EXPECT_DEBUG_DEATH(CordRepBtree::AssertValid(tree, false), ".*");
#endif

  cord_btree_exhaustive_validation.store(true);
  EXPECT_FALSE(CordRepBtree::IsValid(tree));
  EXPECT_FALSE(CordRepBtree::IsValid(tree, true));
  EXPECT_FALSE(CordRepBtree::IsValid(tree, false));
#if defined(GTEST_HAS_DEATH_TEST)
  EXPECT_DEBUG_DEATH(CordRepBtree::AssertValid(tree), ".*");
  EXPECT_DEBUG_DEATH(CordRepBtree::AssertValid(tree, true), ".*");
#endif

  flat->length = 3;
  CordRep::Unref(tree);
}

TEST_P(CordRepBtreeTest, Rebuild) {
  for (size_t size : {3u, 8u, 100u, 10000u, 1000000u}) {
    SCOPED_TRACE(absl::StrCat("Rebuild @", size));

    std::vector<CordRepFlat*> flats;
    for (size_t i = 0; i < size; ++i) {
      flats.push_back(CordRepFlat::New(2));
      flats.back()->Data()[0] = 'x';
      flats.back()->length = 1;
    }

    // Build the tree into 'right', and each so many 'split_limit' edges,
    // combine 'left' + 'right' into a new 'left', and start a new 'right'.
    // This guarantees we get a reasonable amount of chaos in the tree.
    size_t split_count = 0;
    size_t split_limit = 3;
    auto it = flats.begin();
    CordRepBtree* left = nullptr;
    CordRepBtree* right = CordRepBtree::New(*it);
    while (++it != flats.end()) {
      if (++split_count >= split_limit) {
        split_limit += split_limit / 16;
        left = left ? CordRepBtree::Append(left, right) : right;
        right = CordRepBtree::New(*it);
      } else {
        right = CordRepBtree::Append(right, *it);
      }
    }

    // Finalize tree
    left = left ? CordRepBtree::Append(left, right) : right;

    // Rebuild
    AutoUnref ref;
    left = ref.Add(CordRepBtree::Rebuild(ref.RefIf(shared(), left)));
    ASSERT_TRUE(CordRepBtree::IsValid(left));

    // Verify we have the exact same edges in the exact same order.
    bool ok = true;
    it = flats.begin();
    CordVisitReps(left, [&](CordRep* edge) {
      if (edge->tag < FLAT) return;
      ok = ok && (it != flats.end() && *it++ == edge);
    });
    EXPECT_TRUE(ok && it == flats.end()) << "Rebuild edges mismatch";
  }
}

// Convenience helper for CordRepBtree::ExtractAppendBuffer
CordRepBtree::ExtractResult ExtractLast(CordRepBtree* input, size_t cap = 1) {
  return CordRepBtree::ExtractAppendBuffer(input, cap);
}

TEST(CordRepBtreeTest, ExtractAppendBufferLeafSingleFlat) {
  CordRep* flat = MakeFlat("Abc");
  CordRepBtree* leaf = CordRepBtree::Create(flat);
  EXPECT_THAT(ExtractLast(leaf), EqExtractResult(nullptr, flat));
  CordRep::Unref(flat);
}

TEST(CordRepBtreeTest, ExtractAppendBufferNodeSingleFlat) {
  CordRep* flat = MakeFlat("Abc");
  CordRepBtree* leaf = CordRepBtree::Create(flat);
  CordRepBtree* node = CordRepBtree::New(leaf);
  EXPECT_THAT(ExtractLast(node), EqExtractResult(nullptr, flat));
  CordRep::Unref(flat);
}

TEST(CordRepBtreeTest, ExtractAppendBufferLeafTwoFlats) {
  std::vector<CordRep*> flats = CreateFlatsFromString("abcdef", 3);
  CordRepBtree* leaf = CreateTree(flats);
  EXPECT_THAT(ExtractLast(leaf), EqExtractResult(flats[0], flats[1]));
  CordRep::Unref(flats[0]);
  CordRep::Unref(flats[1]);
}

TEST(CordRepBtreeTest, ExtractAppendBufferNodeTwoFlats) {
  std::vector<CordRep*> flats = CreateFlatsFromString("abcdef", 3);
  CordRepBtree* leaf = CreateTree(flats);
  CordRepBtree* node = CordRepBtree::New(leaf);
  EXPECT_THAT(ExtractLast(node), EqExtractResult(flats[0], flats[1]));
  CordRep::Unref(flats[0]);
  CordRep::Unref(flats[1]);
}

TEST(CordRepBtreeTest, ExtractAppendBufferNodeTwoFlatsInTwoLeafs) {
  std::vector<CordRep*> flats = CreateFlatsFromString("abcdef", 3);
  CordRepBtree* leaf1 = CordRepBtree::Create(flats[0]);
  CordRepBtree* leaf2 = CordRepBtree::Create(flats[1]);
  CordRepBtree* node = CordRepBtree::New(leaf1, leaf2);
  EXPECT_THAT(ExtractLast(node), EqExtractResult(flats[0], flats[1]));
  CordRep::Unref(flats[0]);
  CordRep::Unref(flats[1]);
}

TEST(CordRepBtreeTest, ExtractAppendBufferLeafThreeFlats) {
  std::vector<CordRep*> flats = CreateFlatsFromString("abcdefghi", 3);
  CordRepBtree* leaf = CreateTree(flats);
  EXPECT_THAT(ExtractLast(leaf), EqExtractResult(leaf, flats[2]));
  CordRep::Unref(flats[2]);
  CordRep::Unref(leaf);
}

TEST(CordRepBtreeTest, ExtractAppendBufferNodeThreeFlatsRightNoFolding) {
  CordRep* flat = MakeFlat("Abc");
  std::vector<CordRep*> flats = CreateFlatsFromString("defghi", 3);
  CordRepBtree* leaf1 = CordRepBtree::Create(flat);
  CordRepBtree* leaf2 = CreateTree(flats);
  CordRepBtree* node = CordRepBtree::New(leaf1, leaf2);
  EXPECT_THAT(ExtractLast(node), EqExtractResult(node, flats[1]));
  EXPECT_THAT(node->Edges(), ElementsAre(leaf1, leaf2));
  EXPECT_THAT(leaf1->Edges(), ElementsAre(flat));
  EXPECT_THAT(leaf2->Edges(), ElementsAre(flats[0]));
  CordRep::Unref(node);
  CordRep::Unref(flats[1]);
}

TEST(CordRepBtreeTest, ExtractAppendBufferNodeThreeFlatsRightLeafFolding) {
  CordRep* flat = MakeFlat("Abc");
  std::vector<CordRep*> flats = CreateFlatsFromString("defghi", 3);
  CordRepBtree* leaf1 = CreateTree(flats);
  CordRepBtree* leaf2 = CordRepBtree::Create(flat);
  CordRepBtree* node = CordRepBtree::New(leaf1, leaf2);
  EXPECT_THAT(ExtractLast(node), EqExtractResult(leaf1, flat));
  EXPECT_THAT(leaf1->Edges(), ElementsAreArray(flats));
  CordRep::Unref(leaf1);
  CordRep::Unref(flat);
}

TEST(CordRepBtreeTest, ExtractAppendBufferNoCapacity) {
  std::vector<CordRep*> flats = CreateFlatsFromString("abcdef", 3);
  CordRepBtree* leaf = CreateTree(flats);
  size_t avail = flats[1]->flat()->Capacity() - flats[1]->length;
  EXPECT_THAT(ExtractLast(leaf, avail + 1), EqExtractResult(leaf, nullptr));
  EXPECT_THAT(ExtractLast(leaf, avail), EqExtractResult(flats[0], flats[1]));
  CordRep::Unref(flats[0]);
  CordRep::Unref(flats[1]);
}

TEST(CordRepBtreeTest, ExtractAppendBufferNotFlat) {
  std::vector<CordRep*> flats = CreateFlatsFromString("abcdef", 3);
  auto substr = MakeSubstring(1, 2, flats[1]);
  CordRepBtree* leaf = CreateTree({flats[0], substr});
  EXPECT_THAT(ExtractLast(leaf), EqExtractResult(leaf, nullptr));
  CordRep::Unref(leaf);
}

TEST(CordRepBtreeTest, ExtractAppendBufferShared) {
  std::vector<CordRep*> flats = CreateFlatsFromString("abcdef", 3);
  CordRepBtree* leaf = CreateTree(flats);

  CordRep::Ref(flats[1]);
  EXPECT_THAT(ExtractLast(leaf), EqExtractResult(leaf, nullptr));
  CordRep::Unref(flats[1]);

  CordRep::Ref(leaf);
  EXPECT_THAT(ExtractLast(leaf), EqExtractResult(leaf, nullptr));
  CordRep::Unref(leaf);

  CordRepBtree* node = CordRepBtree::New(leaf);
  CordRep::Ref(node);
  EXPECT_THAT(ExtractLast(node), EqExtractResult(node, nullptr));
  CordRep::Unref(node);

  CordRep::Unref(node);
}

}  // namespace
}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl
