// Copyright 2016 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/http2/hpack/decoder/hpack_block_collector.h"

#include <algorithm>
#include <memory>

#include "base/logging.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h"

using ::testing::AssertionResult;
using ::testing::AssertionSuccess;

namespace http2 {
namespace test {

HpackBlockCollector::HpackBlockCollector() = default;
HpackBlockCollector::HpackBlockCollector(const HpackBlockCollector& other)
    : pending_entry_(other.pending_entry_), entries_(other.entries_) {}
HpackBlockCollector::~HpackBlockCollector() = default;

void HpackBlockCollector::OnIndexedHeader(size_t index) {
  pending_entry_.OnIndexedHeader(index);
  PushPendingEntry();
}
void HpackBlockCollector::OnDynamicTableSizeUpdate(size_t size) {
  pending_entry_.OnDynamicTableSizeUpdate(size);
  PushPendingEntry();
}
void HpackBlockCollector::OnStartLiteralHeader(HpackEntryType header_type,
                                               size_t maybe_name_index) {
  pending_entry_.OnStartLiteralHeader(header_type, maybe_name_index);
}
void HpackBlockCollector::OnNameStart(bool huffman_encoded, size_t len) {
  pending_entry_.OnNameStart(huffman_encoded, len);
}
void HpackBlockCollector::OnNameData(const char* data, size_t len) {
  pending_entry_.OnNameData(data, len);
}
void HpackBlockCollector::OnNameEnd() {
  pending_entry_.OnNameEnd();
}
void HpackBlockCollector::OnValueStart(bool huffman_encoded, size_t len) {
  pending_entry_.OnValueStart(huffman_encoded, len);
}
void HpackBlockCollector::OnValueData(const char* data, size_t len) {
  pending_entry_.OnValueData(data, len);
}
void HpackBlockCollector::OnValueEnd() {
  pending_entry_.OnValueEnd();
  PushPendingEntry();
}

void HpackBlockCollector::PushPendingEntry() {
  EXPECT_TRUE(pending_entry_.IsComplete());
  DVLOG(2) << "PushPendingEntry: " << pending_entry_;
  entries_.push_back(pending_entry_);
  EXPECT_TRUE(entries_.back().IsComplete());
  pending_entry_.Clear();
}
void HpackBlockCollector::Clear() {
  pending_entry_.Clear();
  entries_.clear();
}

void HpackBlockCollector::ExpectIndexedHeader(size_t index) {
  entries_.push_back(
      HpackEntryCollector(HpackEntryType::kIndexedHeader, index));
}
void HpackBlockCollector::ExpectDynamicTableSizeUpdate(size_t size) {
  entries_.push_back(
      HpackEntryCollector(HpackEntryType::kDynamicTableSizeUpdate, size));
}
void HpackBlockCollector::ExpectNameIndexAndLiteralValue(
    HpackEntryType type,
    size_t index,
    bool value_huffman,
    const Http2String& value) {
  entries_.push_back(HpackEntryCollector(type, index, value_huffman, value));
}
void HpackBlockCollector::ExpectLiteralNameAndValue(HpackEntryType type,
                                                    bool name_huffman,
                                                    const Http2String& name,
                                                    bool value_huffman,
                                                    const Http2String& value) {
  entries_.push_back(
      HpackEntryCollector(type, name_huffman, name, value_huffman, value));
}

void HpackBlockCollector::ShuffleEntries(Http2Random* rng) {
  std::shuffle(entries_.begin(), entries_.end(), *rng);
}

void HpackBlockCollector::AppendToHpackBlockBuilder(
    HpackBlockBuilder* hbb) const {
  CHECK(IsNotPending());
  for (const auto& entry : entries_) {
    entry.AppendToHpackBlockBuilder(hbb);
  }
}

AssertionResult HpackBlockCollector::ValidateSoleIndexedHeader(
    size_t ndx) const {
  VERIFY_TRUE(pending_entry_.IsClear());
  VERIFY_EQ(1u, entries_.size());
  VERIFY_TRUE(entries_.front().ValidateIndexedHeader(ndx));
  return AssertionSuccess();
}
AssertionResult HpackBlockCollector::ValidateSoleLiteralValueHeader(
    HpackEntryType expected_type,
    size_t expected_index,
    bool expected_value_huffman,
    Http2StringPiece expected_value) const {
  VERIFY_TRUE(pending_entry_.IsClear());
  VERIFY_EQ(1u, entries_.size());
  VERIFY_TRUE(entries_.front().ValidateLiteralValueHeader(
      expected_type, expected_index, expected_value_huffman, expected_value));
  return AssertionSuccess();
}
AssertionResult HpackBlockCollector::ValidateSoleLiteralNameValueHeader(
    HpackEntryType expected_type,
    bool expected_name_huffman,
    Http2StringPiece expected_name,
    bool expected_value_huffman,
    Http2StringPiece expected_value) const {
  VERIFY_TRUE(pending_entry_.IsClear());
  VERIFY_EQ(1u, entries_.size());
  VERIFY_TRUE(entries_.front().ValidateLiteralNameValueHeader(
      expected_type, expected_name_huffman, expected_name,
      expected_value_huffman, expected_value));
  return AssertionSuccess();
}
AssertionResult HpackBlockCollector::ValidateSoleDynamicTableSizeUpdate(
    size_t size) const {
  VERIFY_TRUE(pending_entry_.IsClear());
  VERIFY_EQ(1u, entries_.size());
  VERIFY_TRUE(entries_.front().ValidateDynamicTableSizeUpdate(size));
  return AssertionSuccess();
}

AssertionResult HpackBlockCollector::VerifyEq(
    const HpackBlockCollector& that) const {
  VERIFY_EQ(pending_entry_, that.pending_entry_);
  VERIFY_EQ(entries_, that.entries_);
  return AssertionSuccess();
}

}  // namespace test
}  // namespace http2
