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

#include "net/third_party/quiche/src/http2/platform/api/http2_estimate_memory_usage.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_logging.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_macros.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h"

namespace http2 {

HpackWholeEntryBuffer::HpackWholeEntryBuffer(HpackWholeEntryListener* listener,
                                             size_t max_string_size_bytes)
    : max_string_size_bytes_(max_string_size_bytes) {
  set_listener(listener);
}
HpackWholeEntryBuffer::~HpackWholeEntryBuffer() = default;

void HpackWholeEntryBuffer::set_listener(HpackWholeEntryListener* listener) {
  listener_ = HTTP2_DIE_IF_NULL(listener);
}

void HpackWholeEntryBuffer::set_max_string_size_bytes(
    size_t max_string_size_bytes) {
  max_string_size_bytes_ = max_string_size_bytes;
}

void HpackWholeEntryBuffer::BufferStringsIfUnbuffered() {
  name_.BufferStringIfUnbuffered();
  value_.BufferStringIfUnbuffered();
}

size_t HpackWholeEntryBuffer::EstimateMemoryUsage() const {
  return Http2EstimateMemoryUsage(name_) + Http2EstimateMemoryUsage(value_);
}

void HpackWholeEntryBuffer::OnIndexedHeader(size_t index) {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnIndexedHeader: index=" << index;
  listener_->OnIndexedHeader(index);
}

void HpackWholeEntryBuffer::OnStartLiteralHeader(HpackEntryType entry_type,
                                                 size_t maybe_name_index) {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnStartLiteralHeader: entry_type="
                 << entry_type << ",  maybe_name_index=" << maybe_name_index;
  entry_type_ = entry_type;
  maybe_name_index_ = maybe_name_index;
}

void HpackWholeEntryBuffer::OnNameStart(bool huffman_encoded, size_t len) {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameStart: huffman_encoded="
                 << (huffman_encoded ? "true" : "false") << ",  len=" << len;
  DCHECK_EQ(maybe_name_index_, 0u);
  if (!error_detected_) {
    if (len > max_string_size_bytes_) {
      HTTP2_DVLOG(1) << "Name length (" << len << ") is longer than permitted ("
                     << max_string_size_bytes_ << ")";
      ReportError("HPACK entry name size is too long.");
      return;
    }
    name_.OnStart(huffman_encoded, len);
  }
}

void HpackWholeEntryBuffer::OnNameData(const char* data, size_t len) {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameData: len=" << len
                 << " data:\n"
                 << Http2HexDump(Http2StringPiece(data, len));
  DCHECK_EQ(maybe_name_index_, 0u);
  if (!error_detected_ && !name_.OnData(data, len)) {
    ReportError("Error decoding HPACK entry name.");
  }
}

void HpackWholeEntryBuffer::OnNameEnd() {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnNameEnd";
  DCHECK_EQ(maybe_name_index_, 0u);
  if (!error_detected_ && !name_.OnEnd()) {
    ReportError("Error decoding HPACK entry name.");
  }
}

void HpackWholeEntryBuffer::OnValueStart(bool huffman_encoded, size_t len) {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueStart: huffman_encoded="
                 << (huffman_encoded ? "true" : "false") << ",  len=" << len;
  if (!error_detected_) {
    if (len > max_string_size_bytes_) {
      HTTP2_DVLOG(1) << "Value length (" << len
                     << ") is longer than permitted (" << max_string_size_bytes_
                     << ")";
      ReportError("HPACK entry value size is too long.");
      return;
    }
    value_.OnStart(huffman_encoded, len);
  }
}

void HpackWholeEntryBuffer::OnValueData(const char* data, size_t len) {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueData: len=" << len
                 << " data:\n"
                 << Http2HexDump(Http2StringPiece(data, len));
  if (!error_detected_ && !value_.OnData(data, len)) {
    ReportError("Error decoding HPACK entry value.");
  }
}

void HpackWholeEntryBuffer::OnValueEnd() {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnValueEnd";
  if (error_detected_) {
    return;
  }
  if (!value_.OnEnd()) {
    ReportError("Error decoding HPACK entry value.");
    return;
  }
  if (maybe_name_index_ == 0) {
    listener_->OnLiteralNameAndValue(entry_type_, &name_, &value_);
    name_.Reset();
  } else {
    listener_->OnNameIndexAndLiteralValue(entry_type_, maybe_name_index_,
                                          &value_);
  }
  value_.Reset();
}

void HpackWholeEntryBuffer::OnDynamicTableSizeUpdate(size_t size) {
  HTTP2_DVLOG(2) << "HpackWholeEntryBuffer::OnDynamicTableSizeUpdate: size="
                 << size;
  listener_->OnDynamicTableSizeUpdate(size);
}

void HpackWholeEntryBuffer::ReportError(Http2StringPiece error_message) {
  if (!error_detected_) {
    HTTP2_DVLOG(1) << "HpackWholeEntryBuffer::ReportError: " << error_message;
    error_detected_ = true;
    listener_->OnHpackDecodeError(error_message);
    listener_ = HpackWholeEntryNoOpListener::NoOpListener();
  }
}

}  // namespace http2
