/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "logging/rtc_event_log/encoder/delta_encoding.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <limits>
#include <numeric>
#include <optional>
#include <string>
#include <tuple>
#include <vector>

#include "rtc_base/checks.h"
#include "rtc_base/random.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {

void SetFixedLengthEncoderDeltaSignednessForTesting(bool signedness);
void UnsetFixedLengthEncoderDeltaSignednessForTesting();

namespace {

using ::testing::Each;
using ::testing::Eq;

enum class DeltaSignedness { kNoOverride, kForceUnsigned, kForceSigned };

void MaybeSetSignedness(DeltaSignedness signedness) {
  switch (signedness) {
    case DeltaSignedness::kNoOverride:
      UnsetFixedLengthEncoderDeltaSignednessForTesting();
      return;
    case DeltaSignedness::kForceUnsigned:
      SetFixedLengthEncoderDeltaSignednessForTesting(false);
      return;
    case DeltaSignedness::kForceSigned:
      SetFixedLengthEncoderDeltaSignednessForTesting(true);
      return;
  }
  RTC_DCHECK_NOTREACHED();
}

uint64_t RandomWithMaxBitWidth(Random* prng, uint64_t max_width) {
  RTC_DCHECK_GE(max_width, 1u);
  RTC_DCHECK_LE(max_width, 64u);

  const uint64_t low = prng->Rand(std::numeric_limits<uint32_t>::max());
  const uint64_t high =
      max_width > 32u ? prng->Rand(std::numeric_limits<uint32_t>::max()) : 0u;

  const uint64_t random_before_mask = (high << 32) | low;

  if (max_width < 64) {
    return random_before_mask & ((static_cast<uint64_t>(1) << max_width) - 1);
  } else {
    return random_before_mask;
  }
}

// Encodes `values` based on `base`, then decodes the result and makes sure
// that it is equal to the original input.
// If `encoded_string` is non-null, the encoded result will also be written
// into it.
void TestEncodingAndDecoding(std::optional<uint64_t> base,
                             const std::vector<std::optional<uint64_t>>& values,
                             std::string* encoded_string = nullptr) {
  const std::string encoded = EncodeDeltas(base, values);
  if (encoded_string) {
    *encoded_string = encoded;
  }

  const std::vector<std::optional<uint64_t>> decoded =
      DecodeDeltas(encoded, base, values.size());

  EXPECT_EQ(decoded, values);
}

std::vector<std::optional<uint64_t>> CreateSequenceByFirstValue(
    uint64_t first,
    size_t sequence_length) {
  std::vector<std::optional<uint64_t>> sequence(sequence_length);
  std::iota(sequence.begin(), sequence.end(), first);
  return sequence;
}

std::vector<std::optional<uint64_t>> CreateSequenceByLastValue(
    uint64_t last,
    size_t num_values) {
  const uint64_t first = last - num_values + 1;
  std::vector<std::optional<uint64_t>> result(num_values);
  std::iota(result.begin(), result.end(), first);
  return result;
}

// If `sequence_length` is greater than the number of deltas, the sequence of
// deltas will wrap around.
std::vector<std::optional<uint64_t>> CreateSequenceByOptionalDeltas(
    uint64_t first,
    const std::vector<std::optional<uint64_t>>& deltas,
    size_t sequence_length) {
  RTC_DCHECK_GE(sequence_length, 1);

  std::vector<std::optional<uint64_t>> sequence(sequence_length);

  uint64_t previous = first;
  for (size_t i = 0, next_delta_index = 0; i < sequence.size(); ++i) {
    if (deltas[next_delta_index].has_value()) {
      sequence[i] =
          std::optional<uint64_t>(previous + deltas[next_delta_index].value());
      previous = sequence[i].value();
    }
    next_delta_index = (next_delta_index + 1) % deltas.size();
  }

  return sequence;
}

size_t EncodingLengthUpperBound(size_t delta_max_bit_width,
                                size_t num_of_deltas,
                                DeltaSignedness signedness_override) {
  std::optional<size_t> smallest_header_size_bytes;
  switch (signedness_override) {
    case DeltaSignedness::kNoOverride:
    case DeltaSignedness::kForceUnsigned:
      smallest_header_size_bytes = 1;
      break;
    case DeltaSignedness::kForceSigned:
      smallest_header_size_bytes = 2;
      break;
  }
  RTC_DCHECK(smallest_header_size_bytes);

  return delta_max_bit_width * num_of_deltas + *smallest_header_size_bytes;
}

// If `sequence_length` is greater than the number of deltas, the sequence of
// deltas will wrap around.
std::vector<std::optional<uint64_t>> CreateSequenceByDeltas(
    uint64_t first,
    const std::vector<uint64_t>& deltas,
    size_t sequence_length) {
  RTC_DCHECK(!deltas.empty());
  std::vector<std::optional<uint64_t>> optional_deltas(deltas.size());
  for (size_t i = 0; i < deltas.size(); ++i) {
    optional_deltas[i] = std::optional<uint64_t>(deltas[i]);
  }
  return CreateSequenceByOptionalDeltas(first, optional_deltas,
                                        sequence_length);
}

// Tests of the delta encoding, parameterized by the number of values
// in the sequence created by the test.
class DeltaEncodingTest
    : public ::testing::TestWithParam<
          std::tuple<DeltaSignedness, size_t, bool, uint64_t>> {
 public:
  DeltaEncodingTest()
      : signedness_(std::get<0>(GetParam())),
        num_of_values_(std::get<1>(GetParam())),
        optional_values_(std::get<2>(GetParam())),
        partial_random_seed_(std::get<3>(GetParam())) {
    MaybeSetSignedness(signedness_);
  }

  ~DeltaEncodingTest() override = default;

  // Running with the same seed for all variants would make all tests start
  // with the same sequence; avoid this by making the seed different.
  uint64_t Seed() const {
    // Multiply everything but by different primes to produce unique results.
    return 2 * static_cast<uint64_t>(signedness_) + 3 * num_of_values_ +
           5 * optional_values_ + 7 * partial_random_seed_;
  }

  const DeltaSignedness signedness_;
  const uint64_t num_of_values_;
  const bool optional_values_;
  const uint64_t partial_random_seed_;  // Explained where it's used.
};

TEST_P(DeltaEncodingTest, AllValuesEqualToExistentBaseValue) {
  const std::optional<uint64_t> base(3432);
  std::vector<std::optional<uint64_t>> values(num_of_values_);
  std::fill(values.begin(), values.end(), base);
  std::string encoded;
  TestEncodingAndDecoding(base, values, &encoded);

  // Additional requirement - the encoding should be efficient in this
  // case - the empty string will be used.
  EXPECT_TRUE(encoded.empty());
}

TEST_P(DeltaEncodingTest, AllValuesEqualToNonExistentBaseValue) {
  if (!optional_values_) {
    return;  // Test irrelevant for this case.
  }

  const std::optional<uint64_t> base;
  std::vector<std::optional<uint64_t>> values(num_of_values_);
  std::fill(values.begin(), values.end(), base);
  std::string encoded;
  TestEncodingAndDecoding(base, values, &encoded);

  // Additional requirement - the encoding should be efficient in this
  // case - the empty string will be used.
  EXPECT_TRUE(encoded.empty());
}

TEST_P(DeltaEncodingTest, BaseNonExistentButSomeOtherValuesExist) {
  if (!optional_values_) {
    return;  // Test irrelevant for this case.
  }

  const std::optional<uint64_t> base;
  std::vector<std::optional<uint64_t>> values(num_of_values_);

  Random prng(Seed());

  const uint64_t max_bit_width = 1 + prng.Rand(63);  // [1, 64]

  for (size_t i = 0; i < values.size();) {
    // Leave a random number of values as non-existent.
    const size_t non_existent_count = prng.Rand(values.size() - i - 1);
    i += non_existent_count;

    // Assign random values to a random number of values. (At least one, to
    // prevent this iteration of the outer loop from being a no-op.)
    const size_t existent_count =
        std::max<size_t>(prng.Rand(values.size() - i - 1), 1);
    for (size_t j = 0; j < existent_count; ++j) {
      values[i + j] = RandomWithMaxBitWidth(&prng, max_bit_width);
    }
    i += existent_count;
  }

  TestEncodingAndDecoding(base, values);
}

TEST_P(DeltaEncodingTest, MinDeltaNoWrapAround) {
  const std::optional<uint64_t> base(3432);

  auto values = CreateSequenceByFirstValue(base.value() + 1, num_of_values_);
  ASSERT_GT(values[values.size() - 1], base) << "Sanity; must not wrap around";

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    values[0] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

TEST_P(DeltaEncodingTest, BigDeltaNoWrapAround) {
  const uint64_t kBigDelta = 132828;
  const std::optional<uint64_t> base(3432);

  auto values =
      CreateSequenceByFirstValue(base.value() + kBigDelta, num_of_values_);
  ASSERT_GT(values[values.size() - 1], base) << "Sanity; must not wrap around";

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    values[0] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

TEST_P(DeltaEncodingTest, MaxDeltaNoWrapAround) {
  const std::optional<uint64_t> base(3432);

  auto values = CreateSequenceByLastValue(std::numeric_limits<uint64_t>::max(),
                                          num_of_values_);
  ASSERT_GT(values[values.size() - 1], base) << "Sanity; must not wrap around";

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    values[0] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

TEST_P(DeltaEncodingTest, SmallDeltaWithWrapAroundComparedToBase) {
  if (optional_values_ && num_of_values_ == 1) {
    return;  // Inapplicable
  }

  const std::optional<uint64_t> base(std::numeric_limits<uint64_t>::max());

  auto values = CreateSequenceByDeltas(*base, {1, 10, 3}, num_of_values_);
  ASSERT_LT(values[0], base) << "Sanity; must wrap around";

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    values[1] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

TEST_P(DeltaEncodingTest, SmallDeltaWithWrapAroundInValueSequence) {
  if (num_of_values_ == 1 || (optional_values_ && num_of_values_ < 3)) {
    return;  // Inapplicable.
  }

  const std::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() - 2);

  auto values = CreateSequenceByDeltas(*base, {1, 10, 3}, num_of_values_);
  ASSERT_LT(values[values.size() - 1], values[0]) << "Sanity; must wrap around";

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    RTC_DCHECK_GT(values.size() - 1, 1u);  // Wrap around not cancelled.
    values[1] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

// Suppress "integral constant overflow" warning; this is the test's focus.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4307)
#endif
TEST_P(DeltaEncodingTest, BigDeltaWithWrapAroundComparedToBase) {
  if (optional_values_ && num_of_values_ == 1) {
    return;  // Inapplicable
  }

  const uint64_t kBigDelta = 132828;
  const std::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() -
                                     kBigDelta + 3);

  auto values =
      CreateSequenceByFirstValue(base.value() + kBigDelta, num_of_values_);
  ASSERT_LT(values[0], base.value()) << "Sanity; must wrap around";

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    values[1] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

TEST_P(DeltaEncodingTest, BigDeltaWithWrapAroundInValueSequence) {
  if (num_of_values_ == 1 || (optional_values_ && num_of_values_ < 3)) {
    return;  // Inapplicable.
  }

  const uint64_t kBigDelta = 132828;
  const std::optional<uint64_t> base(std::numeric_limits<uint64_t>::max() -
                                     kBigDelta + 3);

  auto values = CreateSequenceByFirstValue(std::numeric_limits<uint64_t>::max(),
                                           num_of_values_);
  ASSERT_LT(values[values.size() - 1], values[0]) << "Sanity; must wrap around";

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    RTC_DCHECK_GT(values.size() - 1, 1u);  // Wrap around not cancelled.
    values[1] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif

TEST_P(DeltaEncodingTest, MaxDeltaWithWrapAroundComparedToBase) {
  if (optional_values_ && num_of_values_ == 1) {
    return;  // Inapplicable
  }

  const std::optional<uint64_t> base(3432);
  auto values = CreateSequenceByFirstValue(*base - 1, num_of_values_);

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    values[1] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

TEST_P(DeltaEncodingTest, MaxDeltaWithWrapAroundInValueSequence) {
  if (num_of_values_ == 1 || (optional_values_ && num_of_values_ < 3)) {
    return;  // Inapplicable.
  }

  const std::optional<uint64_t> base(3432);

  auto values = CreateSequenceByDeltas(
      *base, {0, std::numeric_limits<uint64_t>::max(), 3}, num_of_values_);
  // Wraps around continuously by virtue of being max(); will not ASSERT.

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    RTC_DCHECK_GT(values.size() - 1, 1u);  // Wrap around not cancelled.
    values[1] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

// If num_of_values_ == 1, a zero delta will yield an empty string; that's
// already covered by AllValuesEqualToExistentBaseValue, but it doesn't hurt to
// test again. For all other cases, we have a new test.
TEST_P(DeltaEncodingTest, ZeroDelta) {
  const std::optional<uint64_t> base(3432);

  // Arbitrary sequence of deltas with intentional zero deltas, as well as
  // consecutive zeros.
  const std::vector<uint64_t> deltas = {0,      312, 11, 1,  1, 0, 0, 12,
                                        400321, 3,   3,  12, 5, 0, 6};
  auto values = CreateSequenceByDeltas(base.value(), deltas, num_of_values_);

  if (optional_values_) {
    // Arbitrarily make one of the values non-existent, to force
    // optional-supporting encoding.
    values[0] = std::optional<uint64_t>();
  }

  TestEncodingAndDecoding(base, values);
}

INSTANTIATE_TEST_SUITE_P(
    SignednessOverrideAndNumberOfValuesInSequence,
    DeltaEncodingTest,
    ::testing::Combine(::testing::Values(DeltaSignedness::kNoOverride,
                                         DeltaSignedness::kForceUnsigned,
                                         DeltaSignedness::kForceSigned),
                       ::testing::Values(1, 2, 100, 10000),
                       ::testing::Bool(),
                       ::testing::Values(10, 20, 30)));

// Tests over the quality of the compression (as opposed to its correctness).
// Not to be confused with tests of runtime efficiency.
class DeltaEncodingCompressionQualityTest
    : public ::testing::TestWithParam<
          std::tuple<DeltaSignedness, uint64_t, uint64_t, uint64_t>> {
 public:
  DeltaEncodingCompressionQualityTest()
      : signedness_(std::get<0>(GetParam())),
        delta_max_bit_width_(std::get<1>(GetParam())),
        num_of_values_(std::get<2>(GetParam())),
        partial_random_seed_(std::get<3>(GetParam())) {
    MaybeSetSignedness(signedness_);
  }

  ~DeltaEncodingCompressionQualityTest() override = default;

  // Running with the same seed for all variants would make all tests start
  // with the same sequence; avoid this by making the seed different.
  uint64_t Seed() const {
    // Multiply everything but by different primes to produce unique results.
    return 2 * static_cast<uint64_t>(signedness_) + 3 * delta_max_bit_width_ +
           5 * delta_max_bit_width_ + 7 * num_of_values_ +
           11 * partial_random_seed_;
  }

  const DeltaSignedness signedness_;
  const uint64_t delta_max_bit_width_;
  const uint64_t num_of_values_;
  const uint64_t partial_random_seed_;  // Explained where it's used.
};

// If no wrap-around occurs in the stream, the width of the values does not
// matter to compression performance; only the deltas matter.
TEST_P(DeltaEncodingCompressionQualityTest, BaseDoesNotAffectEfficiency) {
  // 1. Bases which will not produce a wrap-around.
  // 2. The last base - 0xffffffffffffffff - does cause a wrap-around, but
  //    that still works, because the width is 64 anyway, and does not
  //    need to be conveyed explicitly in the encoding header.
  const uint64_t bases[] = {0, 0x55, 0xffffffff,
                            std::numeric_limits<uint64_t>::max()};

  std::vector<uint64_t> deltas(num_of_values_);

  // Allows us to make sure that the deltas do not produce a wrap-around.
  uint64_t last_element[std::size(bases)];
  memcpy(last_element, bases, sizeof(bases));

  // Avoid empty `deltas` due to first element causing wrap-around.
  deltas[0] = 1;
  for (uint64_t& element : last_element) {
    ++element;
  }

  Random prng(Seed());

  for (size_t i = 1; i < deltas.size(); ++i) {
    const uint64_t delta = RandomWithMaxBitWidth(&prng, delta_max_bit_width_);

    bool wrap_around = false;
    for (size_t j = 0; j < std::size(last_element); ++j) {
      last_element[j] += delta;
      if (last_element[j] < bases[j]) {
        wrap_around = true;
        break;
      }
    }

    if (wrap_around) {
      deltas.resize(i);
      break;
    }

    deltas[i] = delta;
  }

  std::string encodings[std::size(bases)];

  for (size_t i = 0; i < std::size(bases); ++i) {
    const auto values =
        CreateSequenceByDeltas(bases[i], deltas, num_of_values_);
    // Produce the encoding and write it to encodings[i].
    // By using TestEncodingAndDecoding() to do this, we also sanity-test
    // the encoding/decoding, though that is not the test's focus.
    TestEncodingAndDecoding(bases[i], values, &encodings[i]);
    EXPECT_LE(encodings[i].length(),
              EncodingLengthUpperBound(delta_max_bit_width_, num_of_values_,
                                       signedness_));
  }

  // Test focus - all of the encodings should be the same, as they are based
  // on the same delta sequence, and do not contain a wrap-around.
  EXPECT_THAT(encodings, Each(Eq(encodings[0])));
}

INSTANTIATE_TEST_SUITE_P(
    SignednessOverrideAndDeltaMaxBitWidthAndNumberOfValuesInSequence,
    DeltaEncodingCompressionQualityTest,
    ::testing::Combine(
        ::testing::Values(DeltaSignedness::kNoOverride,
                          DeltaSignedness::kForceUnsigned,
                          DeltaSignedness::kForceSigned),
        ::testing::Values(1, 4, 8, 15, 16, 17, 31, 32, 33, 63, 64),
        ::testing::Values(1, 2, 100, 10000),
        ::testing::Values(11, 12, 13)));

// Similar to DeltaEncodingTest, but instead of semi-surgically producing
// specific cases, produce large amount of semi-realistic inputs.
class DeltaEncodingFuzzerLikeTest
    : public ::testing::TestWithParam<
          std::tuple<DeltaSignedness, uint64_t, uint64_t, bool, uint64_t>> {
 public:
  DeltaEncodingFuzzerLikeTest()
      : signedness_(std::get<0>(GetParam())),
        delta_max_bit_width_(std::get<1>(GetParam())),
        num_of_values_(std::get<2>(GetParam())),
        optional_values_(std::get<3>(GetParam())),
        partial_random_seed_(std::get<4>(GetParam())) {
    MaybeSetSignedness(signedness_);
  }

  ~DeltaEncodingFuzzerLikeTest() override = default;

  // Running with the same seed for all variants would make all tests start
  // with the same sequence; avoid this by making the seed different.
  uint64_t Seed() const {
    // Multiply everything but by different primes to produce unique results.
    return 2 * static_cast<uint64_t>(signedness_) + 3 * delta_max_bit_width_ +
           5 * delta_max_bit_width_ + 7 * num_of_values_ +
           11 * static_cast<uint64_t>(optional_values_) +
           13 * partial_random_seed_;
  }

  const DeltaSignedness signedness_;
  const uint64_t delta_max_bit_width_;
  const uint64_t num_of_values_;
  const bool optional_values_;
  const uint64_t partial_random_seed_;  // Explained where it's used.
};

TEST_P(DeltaEncodingFuzzerLikeTest, Test) {
  const std::optional<uint64_t> base(3432);

  Random prng(Seed());
  std::vector<std::optional<uint64_t>> deltas(num_of_values_);
  for (size_t i = 0; i < deltas.size(); ++i) {
    if (!optional_values_ || prng.Rand<bool>()) {
      deltas[i] = RandomWithMaxBitWidth(&prng, delta_max_bit_width_);
    }
  }
  const auto values =
      CreateSequenceByOptionalDeltas(base.value(), deltas, num_of_values_);

  TestEncodingAndDecoding(base, values);
}

INSTANTIATE_TEST_SUITE_P(
    SignednessOverrideAndDeltaMaxBitWidthAndNumberOfValuesInSequence,
    DeltaEncodingFuzzerLikeTest,
    ::testing::Combine(
        ::testing::Values(DeltaSignedness::kNoOverride,
                          DeltaSignedness::kForceUnsigned,
                          DeltaSignedness::kForceSigned),
        ::testing::Values(1, 4, 8, 15, 16, 17, 31, 32, 33, 63, 64),
        ::testing::Values(1, 2, 100, 10000),
        ::testing::Bool(),
        ::testing::Values(21, 22, 23)));

class DeltaEncodingSpecificEdgeCasesTest
    : public ::testing::TestWithParam<
          std::tuple<DeltaSignedness, uint64_t, bool>> {
 public:
  DeltaEncodingSpecificEdgeCasesTest() {
    UnsetFixedLengthEncoderDeltaSignednessForTesting();
  }

  ~DeltaEncodingSpecificEdgeCasesTest() override = default;
};

// This case is special because it produces identical forward/backward deltas.
TEST_F(DeltaEncodingSpecificEdgeCasesTest, SignedDeltaWithOnlyTopBitOn) {
  MaybeSetSignedness(DeltaSignedness::kForceSigned);

  const std::optional<uint64_t> base(3432);

  const uint64_t delta = static_cast<uint64_t>(1) << 63;
  const std::vector<std::optional<uint64_t>> values = {base.value() + delta};

  TestEncodingAndDecoding(base, values);
}

TEST_F(DeltaEncodingSpecificEdgeCasesTest, MaximumUnsignedDelta) {
  MaybeSetSignedness(DeltaSignedness::kForceUnsigned);

  const std::optional<uint64_t> base((static_cast<uint64_t>(1) << 63) + 0x123);

  const std::vector<std::optional<uint64_t>> values = {base.value() - 1};

  TestEncodingAndDecoding(base, values);
}

// Check that, if all deltas are set to -1, things still work.
TEST_P(DeltaEncodingSpecificEdgeCasesTest, ReverseSequence) {
  MaybeSetSignedness(std::get<0>(GetParam()));
  const uint64_t width = std::get<1>(GetParam());
  const bool wrap_around = std::get<2>(GetParam());

  const uint64_t value_mask = (width == 64)
                                  ? std::numeric_limits<uint64_t>::max()
                                  : ((static_cast<uint64_t>(1) << width) - 1);

  const uint64_t base = wrap_around ? 1u : (0xf82d3 & value_mask);
  const std::vector<std::optional<uint64_t>> values = {
      (base - 1u) & value_mask, (base - 2u) & value_mask,
      (base - 3u) & value_mask};

  TestEncodingAndDecoding(base, values);
}

INSTANTIATE_TEST_SUITE_P(
    _,
    DeltaEncodingSpecificEdgeCasesTest,
    ::testing::Combine(
        ::testing::Values(DeltaSignedness::kNoOverride,
                          DeltaSignedness::kForceUnsigned,
                          DeltaSignedness::kForceSigned),
        ::testing::Values(1, 4, 8, 15, 16, 17, 31, 32, 33, 63, 64),
        ::testing::Bool()));

}  // namespace
}  // namespace webrtc
