// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/core/qpack/qpack_progressive_decoder.h"

#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"

namespace quic {
namespace test {
namespace {

// For testing valid decodings, the Encoded Required Insert Count is calculated
// from Required Insert Count, so that there is an expected value to compare
// the decoded value against, and so that intricate inequalities can be
// documented.
struct {
  uint64_t required_insert_count;
  uint64_t max_entries;
  uint64_t total_number_of_inserts;
} kTestData[] = {
    // Maximum dynamic table capacity is zero.
    {0, 0, 0},
    // No dynamic entries in header.
    {0, 100, 0},
    {0, 100, 500},
    // Required Insert Count has not wrapped around yet, no entries evicted.
    {15, 100, 25},
    {20, 100, 10},
    // Required Insert Count has not wrapped around yet, some entries evicted.
    {90, 100, 110},
    // Required Insert Count has wrapped around.
    {234, 100, 180},
    // Required Insert Count has wrapped around many times.
    {5678, 100, 5701},
    // Lowest and highest possible Required Insert Count values
    // for given MaxEntries and total number of insertions.
    {401, 100, 500},
    {600, 100, 500}};

uint64_t EncodeRequiredInsertCount(uint64_t required_insert_count,
                                   uint64_t max_entries) {
  if (required_insert_count == 0) {
    return 0;
  }

  return required_insert_count % (2 * max_entries) + 1;
}

TEST(QpackProgressiveDecoderTest, DecodeRequiredInsertCount) {
  for (size_t i = 0; i < QUIC_ARRAYSIZE(kTestData); ++i) {
    const uint64_t required_insert_count = kTestData[i].required_insert_count;
    const uint64_t max_entries = kTestData[i].max_entries;
    const uint64_t total_number_of_inserts =
        kTestData[i].total_number_of_inserts;

    if (required_insert_count != 0) {
      // Dynamic entries cannot be referenced if dynamic table capacity is zero.
      ASSERT_LT(0u, max_entries) << i;
      // Entry |total_number_of_inserts - 1 - max_entries| and earlier entries
      // are evicted.  Entry |required_insert_count - 1| is referenced.  No
      // evicted entry can be referenced.
      ASSERT_LT(total_number_of_inserts, required_insert_count + max_entries)
          << i;
      // Entry |required_insert_count - 1 - max_entries| and earlier entries are
      // evicted, entry |total_number_of_inserts - 1| is the last acknowledged
      // entry.  Every evicted entry must be acknowledged.
      ASSERT_LE(required_insert_count, total_number_of_inserts + max_entries)
          << i;
    }

    uint64_t encoded_required_insert_count =
        EncodeRequiredInsertCount(required_insert_count, max_entries);

    // Initialize to a value different from the expected output to confirm that
    // DecodeRequiredInsertCount() modifies the value of
    // |decoded_required_insert_count|.
    uint64_t decoded_required_insert_count = required_insert_count + 1;
    EXPECT_TRUE(QpackProgressiveDecoder::DecodeRequiredInsertCount(
        encoded_required_insert_count, max_entries, total_number_of_inserts,
        &decoded_required_insert_count))
        << i;

    EXPECT_EQ(decoded_required_insert_count, required_insert_count) << i;
  }
}

// Failures are tested with hardcoded values for encoded required insert count,
// to provide test coverage for values that would never be produced by a well
// behaved encoding function.
struct {
  uint64_t encoded_required_insert_count;
  uint64_t max_entries;
  uint64_t total_number_of_inserts;
} kInvalidTestData[] = {
    // Maximum dynamic table capacity is zero, yet header block
    // claims to have a reference to a dynamic table entry.
    {1, 0, 0},
    {9, 0, 0},
    // Examples from
    // https://github.com/quicwg/base-drafts/issues/2112#issue-389626872.
    {1, 10, 2},
    {18, 10, 2},
    // Encoded Required Insert Count value too small or too large
    // for given MaxEntries and total number of insertions.
    {400, 100, 500},
    {601, 100, 500}};

TEST(QpackProgressiveDecoderTest, DecodeRequiredInsertCountError) {
  for (size_t i = 0; i < QUIC_ARRAYSIZE(kInvalidTestData); ++i) {
    uint64_t decoded_required_insert_count = 0;
    EXPECT_FALSE(QpackProgressiveDecoder::DecodeRequiredInsertCount(
        kInvalidTestData[i].encoded_required_insert_count,
        kInvalidTestData[i].max_entries,
        kInvalidTestData[i].total_number_of_inserts,
        &decoded_required_insert_count))
        << i;
  }
}

}  // namespace
}  // namespace test
}  // namespace quic
