// 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_entry_collector.h"

#include "base/logging.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "net/third_party/quiche/src/http2/hpack/decoder/hpack_string_collector.h"
#include "net/third_party/quiche/src/http2/hpack/http2_hpack_constants.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h"

using ::testing::AssertionResult;

namespace http2 {
namespace test {
namespace {

const HpackEntryType kInvalidHeaderType = static_cast<HpackEntryType>(99);
const size_t kInvalidIndex = 99999999;

}  // namespace

HpackEntryCollector::HpackEntryCollector() {
  Clear();
}

HpackEntryCollector::HpackEntryCollector(const HpackEntryCollector& other) =
    default;

HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
                                         size_t index_or_size)
    : header_type_(type), index_(index_or_size), started_(true), ended_(true) {}
HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
                                         size_t index,
                                         bool value_huffman,
                                         const Http2String& value)
    : header_type_(type),
      index_(index),
      value_(value, value_huffman),
      started_(true),
      ended_(true) {}
HpackEntryCollector::HpackEntryCollector(HpackEntryType type,
                                         bool name_huffman,
                                         const Http2String& name,
                                         bool value_huffman,
                                         const Http2String& value)
    : header_type_(type),
      index_(0),
      name_(name, name_huffman),
      value_(value, value_huffman),
      started_(true),
      ended_(true) {}

HpackEntryCollector::~HpackEntryCollector() = default;

void HpackEntryCollector::OnIndexedHeader(size_t index) {
  ASSERT_FALSE(started_);
  ASSERT_TRUE(IsClear()) << ToString();
  Init(HpackEntryType::kIndexedHeader, index);
  ended_ = true;
}
void HpackEntryCollector::OnStartLiteralHeader(HpackEntryType header_type,
                                               size_t maybe_name_index) {
  ASSERT_FALSE(started_);
  ASSERT_TRUE(IsClear()) << ToString();
  Init(header_type, maybe_name_index);
}
void HpackEntryCollector::OnNameStart(bool huffman_encoded, size_t len) {
  ASSERT_TRUE(started_);
  ASSERT_FALSE(ended_);
  ASSERT_FALSE(IsClear());
  ASSERT_TRUE(LiteralNameExpected()) << ToString();
  name_.OnStringStart(huffman_encoded, len);
}
void HpackEntryCollector::OnNameData(const char* data, size_t len) {
  ASSERT_TRUE(started_);
  ASSERT_FALSE(ended_);
  ASSERT_TRUE(LiteralNameExpected()) << ToString();
  ASSERT_TRUE(name_.IsInProgress());
  name_.OnStringData(data, len);
}
void HpackEntryCollector::OnNameEnd() {
  ASSERT_TRUE(started_);
  ASSERT_FALSE(ended_);
  ASSERT_TRUE(LiteralNameExpected()) << ToString();
  ASSERT_TRUE(name_.IsInProgress());
  name_.OnStringEnd();
}
void HpackEntryCollector::OnValueStart(bool huffman_encoded, size_t len) {
  ASSERT_TRUE(started_);
  ASSERT_FALSE(ended_);
  if (LiteralNameExpected()) {
    ASSERT_TRUE(name_.HasEnded());
  }
  ASSERT_TRUE(LiteralValueExpected()) << ToString();
  ASSERT_TRUE(value_.IsClear()) << value_.ToString();
  value_.OnStringStart(huffman_encoded, len);
}
void HpackEntryCollector::OnValueData(const char* data, size_t len) {
  ASSERT_TRUE(started_);
  ASSERT_FALSE(ended_);
  ASSERT_TRUE(LiteralValueExpected()) << ToString();
  ASSERT_TRUE(value_.IsInProgress());
  value_.OnStringData(data, len);
}
void HpackEntryCollector::OnValueEnd() {
  ASSERT_TRUE(started_);
  ASSERT_FALSE(ended_);
  ASSERT_TRUE(LiteralValueExpected()) << ToString();
  ASSERT_TRUE(value_.IsInProgress());
  value_.OnStringEnd();
  ended_ = true;
}
void HpackEntryCollector::OnDynamicTableSizeUpdate(size_t size) {
  ASSERT_FALSE(started_);
  ASSERT_TRUE(IsClear()) << ToString();
  Init(HpackEntryType::kDynamicTableSizeUpdate, size);
  ended_ = true;
}

void HpackEntryCollector::Clear() {
  header_type_ = kInvalidHeaderType;
  index_ = kInvalidIndex;
  name_.Clear();
  value_.Clear();
  started_ = ended_ = false;
}
bool HpackEntryCollector::IsClear() const {
  return header_type_ == kInvalidHeaderType && index_ == kInvalidIndex &&
         name_.IsClear() && value_.IsClear() && !started_ && !ended_;
}
bool HpackEntryCollector::IsComplete() const {
  return started_ && ended_;
}
bool HpackEntryCollector::LiteralNameExpected() const {
  switch (header_type_) {
    case HpackEntryType::kIndexedLiteralHeader:
    case HpackEntryType::kUnindexedLiteralHeader:
    case HpackEntryType::kNeverIndexedLiteralHeader:
      return index_ == 0;
    default:
      return false;
  }
}
bool HpackEntryCollector::LiteralValueExpected() const {
  switch (header_type_) {
    case HpackEntryType::kIndexedLiteralHeader:
    case HpackEntryType::kUnindexedLiteralHeader:
    case HpackEntryType::kNeverIndexedLiteralHeader:
      return true;
    default:
      return false;
  }
}
AssertionResult HpackEntryCollector::ValidateIndexedHeader(
    size_t expected_index) const {
  VERIFY_TRUE(started_);
  VERIFY_TRUE(ended_);
  VERIFY_EQ(HpackEntryType::kIndexedHeader, header_type_);
  VERIFY_EQ(expected_index, index_);
  return ::testing::AssertionSuccess();
}
AssertionResult HpackEntryCollector::ValidateLiteralValueHeader(
    HpackEntryType expected_type,
    size_t expected_index,
    bool expected_value_huffman,
    Http2StringPiece expected_value) const {
  VERIFY_TRUE(started_);
  VERIFY_TRUE(ended_);
  VERIFY_EQ(expected_type, header_type_);
  VERIFY_NE(0u, expected_index);
  VERIFY_EQ(expected_index, index_);
  VERIFY_TRUE(name_.IsClear());
  VERIFY_SUCCESS(value_.Collected(expected_value, expected_value_huffman));
  return ::testing::AssertionSuccess();
}
AssertionResult HpackEntryCollector::ValidateLiteralNameValueHeader(
    HpackEntryType expected_type,
    bool expected_name_huffman,
    Http2StringPiece expected_name,
    bool expected_value_huffman,
    Http2StringPiece expected_value) const {
  VERIFY_TRUE(started_);
  VERIFY_TRUE(ended_);
  VERIFY_EQ(expected_type, header_type_);
  VERIFY_EQ(0u, index_);
  VERIFY_SUCCESS(name_.Collected(expected_name, expected_name_huffman));
  VERIFY_SUCCESS(value_.Collected(expected_value, expected_value_huffman));
  return ::testing::AssertionSuccess();
}
AssertionResult HpackEntryCollector::ValidateDynamicTableSizeUpdate(
    size_t size) const {
  VERIFY_TRUE(started_);
  VERIFY_TRUE(ended_);
  VERIFY_EQ(HpackEntryType::kDynamicTableSizeUpdate, header_type_);
  VERIFY_EQ(index_, size);
  return ::testing::AssertionSuccess();
}

void HpackEntryCollector::AppendToHpackBlockBuilder(
    HpackBlockBuilder* hbb) const {
  ASSERT_TRUE(started_ && ended_) << *this;
  switch (header_type_) {
    case HpackEntryType::kIndexedHeader:
      hbb->AppendIndexedHeader(index_);
      return;

    case HpackEntryType::kDynamicTableSizeUpdate:
      hbb->AppendDynamicTableSizeUpdate(index_);
      return;

    case HpackEntryType::kIndexedLiteralHeader:
    case HpackEntryType::kUnindexedLiteralHeader:
    case HpackEntryType::kNeverIndexedLiteralHeader:
      ASSERT_TRUE(value_.HasEnded()) << *this;
      if (index_ != 0) {
        CHECK(name_.IsClear());
        hbb->AppendNameIndexAndLiteralValue(header_type_, index_,
                                            value_.huffman_encoded, value_.s);
      } else {
        CHECK(name_.HasEnded()) << *this;
        hbb->AppendLiteralNameAndValue(header_type_, name_.huffman_encoded,
                                       name_.s, value_.huffman_encoded,
                                       value_.s);
      }
      return;

    default:
      ADD_FAILURE() << *this;
  }
}

Http2String HpackEntryCollector::ToString() const {
  Http2String result("Type=");
  switch (header_type_) {
    case HpackEntryType::kIndexedHeader:
      result += "IndexedHeader";
      break;
    case HpackEntryType::kDynamicTableSizeUpdate:
      result += "DynamicTableSizeUpdate";
      break;
    case HpackEntryType::kIndexedLiteralHeader:
      result += "IndexedLiteralHeader";
      break;
    case HpackEntryType::kUnindexedLiteralHeader:
      result += "UnindexedLiteralHeader";
      break;
    case HpackEntryType::kNeverIndexedLiteralHeader:
      result += "NeverIndexedLiteralHeader";
      break;
    default:
      if (header_type_ == kInvalidHeaderType) {
        result += "<unset>";
      } else {
        Http2StrAppend(&result, header_type_);
      }
  }
  if (index_ != 0) {
    Http2StrAppend(&result, " Index=", index_);
  }
  if (!name_.IsClear()) {
    Http2StrAppend(&result, " Name", name_.ToString());
  }
  if (!value_.IsClear()) {
    Http2StrAppend(&result, " Value", value_.ToString());
  }
  if (!started_) {
    EXPECT_FALSE(ended_);
    Http2StrAppend(&result, " !started");
  } else if (!ended_) {
    Http2StrAppend(&result, " !ended");
  } else {
    Http2StrAppend(&result, " Complete");
  }
  return result;
}

void HpackEntryCollector::Init(HpackEntryType type, size_t maybe_index) {
  ASSERT_TRUE(IsClear()) << ToString();
  header_type_ = type;
  index_ = maybe_index;
  started_ = true;
}

bool operator==(const HpackEntryCollector& a, const HpackEntryCollector& b) {
  return a.name() == b.name() && a.value() == b.value() &&
         a.index() == b.index() && a.header_type() == b.header_type() &&
         a.started() == b.started() && a.ended() == b.ended();
}
bool operator!=(const HpackEntryCollector& a, const HpackEntryCollector& b) {
  return !(a == b);
}

std::ostream& operator<<(std::ostream& out, const HpackEntryCollector& v) {
  return out << v.ToString();
}

}  // namespace test
}  // namespace http2
