// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/spdy/buffered_spdy_framer.h"

#include <algorithm>
#include <utility>

#include "base/check.h"
#include "base/strings/string_util.h"
#include "base/trace_event/memory_usage_estimator.h"

namespace net {

namespace {

// GOAWAY frame debug data is only buffered up to this many bytes.
size_t kGoAwayDebugDataMaxSize = 1024;

}  // namespace

BufferedSpdyFramer::BufferedSpdyFramer(uint32_t max_header_list_size,
                                       const NetLogWithSource& net_log,
                                       TimeFunc time_func)
    : spdy_framer_(spdy::SpdyFramer::ENABLE_COMPRESSION),
      max_header_list_size_(max_header_list_size),
      net_log_(net_log),
      time_func_(time_func) {
  // Do not bother decoding response header payload above the limit.
  deframer_.GetHpackDecoder()->set_max_decode_buffer_size_bytes(
      max_header_list_size_);
}

BufferedSpdyFramer::~BufferedSpdyFramer() = default;

void BufferedSpdyFramer::set_visitor(
    BufferedSpdyFramerVisitorInterface* visitor) {
  visitor_ = visitor;
  deframer_.set_visitor(this);
}

void BufferedSpdyFramer::set_debug_visitor(
    spdy::SpdyFramerDebugVisitorInterface* debug_visitor) {
  spdy_framer_.set_debug_visitor(debug_visitor);
  deframer_.set_debug_visitor(debug_visitor);
}

void BufferedSpdyFramer::OnError(
    http2::Http2DecoderAdapter::SpdyFramerError spdy_framer_error,
    std::string /*detailed_error*/) {
  visitor_->OnError(spdy_framer_error);
}

void BufferedSpdyFramer::OnHeaders(spdy::SpdyStreamId stream_id,
                                   size_t payload_length,
                                   bool has_priority,
                                   int weight,
                                   spdy::SpdyStreamId parent_stream_id,
                                   bool exclusive,
                                   bool fin,
                                   bool end) {
  frames_received_++;
  DCHECK(!control_frame_fields_.get());
  control_frame_fields_ = std::make_unique<ControlFrameFields>();
  control_frame_fields_->type = spdy::SpdyFrameType::HEADERS;
  control_frame_fields_->stream_id = stream_id;
  control_frame_fields_->has_priority = has_priority;
  if (control_frame_fields_->has_priority) {
    control_frame_fields_->weight = weight;
    control_frame_fields_->parent_stream_id = parent_stream_id;
    control_frame_fields_->exclusive = exclusive;
  }
  control_frame_fields_->fin = fin;
  control_frame_fields_->recv_first_byte_time = time_func_();
}

void BufferedSpdyFramer::OnDataFrameHeader(spdy::SpdyStreamId stream_id,
                                           size_t length,
                                           bool fin) {
  frames_received_++;
  visitor_->OnDataFrameHeader(stream_id, length, fin);
}

void BufferedSpdyFramer::OnStreamFrameData(spdy::SpdyStreamId stream_id,
                                           const char* data,
                                           size_t len) {
  visitor_->OnStreamFrameData(stream_id, data, len);
}

void BufferedSpdyFramer::OnStreamEnd(spdy::SpdyStreamId stream_id) {
  visitor_->OnStreamEnd(stream_id);
}

void BufferedSpdyFramer::OnStreamPadLength(spdy::SpdyStreamId stream_id,
                                           size_t value) {
  // Deliver the stream pad length byte for flow control handling.
  visitor_->OnStreamPadding(stream_id, 1);
}

void BufferedSpdyFramer::OnStreamPadding(spdy::SpdyStreamId stream_id,
                                         size_t len) {
  visitor_->OnStreamPadding(stream_id, len);
}

spdy::SpdyHeadersHandlerInterface* BufferedSpdyFramer::OnHeaderFrameStart(
    spdy::SpdyStreamId stream_id) {
  coalescer_ =
      std::make_unique<HeaderCoalescer>(max_header_list_size_, net_log_);
  return coalescer_.get();
}

void BufferedSpdyFramer::OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) {
  if (coalescer_->error_seen()) {
    visitor_->OnStreamError(stream_id,
                            "Could not parse Spdy Control Frame Header.");
    control_frame_fields_.reset();
    return;
  }
  DCHECK(control_frame_fields_.get());
  switch (control_frame_fields_->type) {
    case spdy::SpdyFrameType::HEADERS:
      visitor_->OnHeaders(
          control_frame_fields_->stream_id, control_frame_fields_->has_priority,
          control_frame_fields_->weight,
          control_frame_fields_->parent_stream_id,
          control_frame_fields_->exclusive, control_frame_fields_->fin,
          coalescer_->release_headers(),
          control_frame_fields_->recv_first_byte_time);
      break;
    case spdy::SpdyFrameType::PUSH_PROMISE:
      visitor_->OnPushPromise(control_frame_fields_->stream_id,
                              control_frame_fields_->promised_stream_id,
                              coalescer_->release_headers());
      break;
    default:
      DCHECK(false) << "Unexpect control frame type: "
                    << control_frame_fields_->type;
      break;
  }
  control_frame_fields_.reset(nullptr);
}

void BufferedSpdyFramer::OnSettings() {
  visitor_->OnSettings();
}

void BufferedSpdyFramer::OnSetting(spdy::SpdySettingsId id, uint32_t value) {
  visitor_->OnSetting(id, value);
}

void BufferedSpdyFramer::OnSettingsAck() {
  visitor_->OnSettingsAck();
}

void BufferedSpdyFramer::OnSettingsEnd() {
  visitor_->OnSettingsEnd();
}

void BufferedSpdyFramer::OnPing(spdy::SpdyPingId unique_id, bool is_ack) {
  visitor_->OnPing(unique_id, is_ack);
}

void BufferedSpdyFramer::OnRstStream(spdy::SpdyStreamId stream_id,
                                     spdy::SpdyErrorCode error_code) {
  visitor_->OnRstStream(stream_id, error_code);
}
void BufferedSpdyFramer::OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
                                  spdy::SpdyErrorCode error_code) {
  DCHECK(!goaway_fields_);
  goaway_fields_ = std::make_unique<GoAwayFields>();
  goaway_fields_->last_accepted_stream_id = last_accepted_stream_id;
  goaway_fields_->error_code = error_code;
}

bool BufferedSpdyFramer::OnGoAwayFrameData(const char* goaway_data,
                                           size_t len) {
  if (len > 0) {
    if (goaway_fields_->debug_data.size() < kGoAwayDebugDataMaxSize) {
      goaway_fields_->debug_data.append(
          goaway_data, std::min(len, kGoAwayDebugDataMaxSize -
                                         goaway_fields_->debug_data.size()));
    }
    return true;
  }
  visitor_->OnGoAway(goaway_fields_->last_accepted_stream_id,
                     goaway_fields_->error_code, goaway_fields_->debug_data);
  goaway_fields_.reset();
  return true;
}

void BufferedSpdyFramer::OnWindowUpdate(spdy::SpdyStreamId stream_id,
                                        int delta_window_size) {
  visitor_->OnWindowUpdate(stream_id, delta_window_size);
}

void BufferedSpdyFramer::OnPushPromise(spdy::SpdyStreamId stream_id,
                                       spdy::SpdyStreamId promised_stream_id,
                                       bool end) {
  frames_received_++;
  DCHECK(!control_frame_fields_.get());
  control_frame_fields_ = std::make_unique<ControlFrameFields>();
  control_frame_fields_->type = spdy::SpdyFrameType::PUSH_PROMISE;
  control_frame_fields_->stream_id = stream_id;
  control_frame_fields_->promised_stream_id = promised_stream_id;
  control_frame_fields_->recv_first_byte_time = time_func_();
}

void BufferedSpdyFramer::OnAltSvc(
    spdy::SpdyStreamId stream_id,
    absl::string_view origin,
    const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
  visitor_->OnAltSvc(stream_id, origin, altsvc_vector);
}

void BufferedSpdyFramer::OnContinuation(spdy::SpdyStreamId stream_id,
                                        size_t payload_length,
                                        bool end) {}

bool BufferedSpdyFramer::OnUnknownFrame(spdy::SpdyStreamId stream_id,
                                        uint8_t frame_type) {
  return visitor_->OnUnknownFrame(stream_id, frame_type);
}

size_t BufferedSpdyFramer::ProcessInput(const char* data, size_t len) {
  return deframer_.ProcessInput(data, len);
}

void BufferedSpdyFramer::UpdateHeaderDecoderTableSize(uint32_t value) {
  deframer_.GetHpackDecoder()->ApplyHeaderTableSizeSetting(value);
}

http2::Http2DecoderAdapter::SpdyFramerError
BufferedSpdyFramer::spdy_framer_error() const {
  return deframer_.spdy_framer_error();
}

http2::Http2DecoderAdapter::SpdyState BufferedSpdyFramer::state() const {
  return deframer_.state();
}

bool BufferedSpdyFramer::MessageFullyRead() {
  return state() == http2::Http2DecoderAdapter::SPDY_FRAME_COMPLETE;
}

bool BufferedSpdyFramer::HasError() {
  return deframer_.HasError();
}

// TODO(jgraettinger): Eliminate uses of this method (prefer
// spdy::SpdyRstStreamIR).
std::unique_ptr<spdy::SpdySerializedFrame> BufferedSpdyFramer::CreateRstStream(
    spdy::SpdyStreamId stream_id,
    spdy::SpdyErrorCode error_code) const {
  spdy::SpdyRstStreamIR rst_ir(stream_id, error_code);
  return std::make_unique<spdy::SpdySerializedFrame>(
      spdy_framer_.SerializeRstStream(rst_ir));
}

// TODO(jgraettinger): Eliminate uses of this method (prefer
// spdy::SpdySettingsIR).
std::unique_ptr<spdy::SpdySerializedFrame> BufferedSpdyFramer::CreateSettings(
    const spdy::SettingsMap& values) const {
  spdy::SpdySettingsIR settings_ir;
  for (const auto& it : values) {
    settings_ir.AddSetting(it.first, it.second);
  }
  return std::make_unique<spdy::SpdySerializedFrame>(
      spdy_framer_.SerializeSettings(settings_ir));
}

// TODO(jgraettinger): Eliminate uses of this method (prefer spdy::SpdyPingIR).
std::unique_ptr<spdy::SpdySerializedFrame> BufferedSpdyFramer::CreatePingFrame(
    spdy::SpdyPingId unique_id,
    bool is_ack) const {
  spdy::SpdyPingIR ping_ir(unique_id);
  ping_ir.set_is_ack(is_ack);
  return std::make_unique<spdy::SpdySerializedFrame>(
      spdy_framer_.SerializePing(ping_ir));
}

// TODO(jgraettinger): Eliminate uses of this method (prefer
// spdy::SpdyWindowUpdateIR).
std::unique_ptr<spdy::SpdySerializedFrame>
BufferedSpdyFramer::CreateWindowUpdate(spdy::SpdyStreamId stream_id,
                                       uint32_t delta_window_size) const {
  spdy::SpdyWindowUpdateIR update_ir(stream_id, delta_window_size);
  return std::make_unique<spdy::SpdySerializedFrame>(
      spdy_framer_.SerializeWindowUpdate(update_ir));
}

// TODO(jgraettinger): Eliminate uses of this method (prefer spdy::SpdyDataIR).
std::unique_ptr<spdy::SpdySerializedFrame> BufferedSpdyFramer::CreateDataFrame(
    spdy::SpdyStreamId stream_id,
    const char* data,
    uint32_t len,
    spdy::SpdyDataFlags flags) {
  spdy::SpdyDataIR data_ir(stream_id, std::string_view(data, len));
  data_ir.set_fin((flags & spdy::DATA_FLAG_FIN) != 0);
  return std::make_unique<spdy::SpdySerializedFrame>(
      spdy_framer_.SerializeData(data_ir));
}

// TODO(jgraettinger): Eliminate uses of this method (prefer
// spdy::SpdyPriorityIR).
std::unique_ptr<spdy::SpdySerializedFrame> BufferedSpdyFramer::CreatePriority(
    spdy::SpdyStreamId stream_id,
    spdy::SpdyStreamId dependency_id,
    int weight,
    bool exclusive) const {
  spdy::SpdyPriorityIR priority_ir(stream_id, dependency_id, weight, exclusive);
  return std::make_unique<spdy::SpdySerializedFrame>(
      spdy_framer_.SerializePriority(priority_ir));
}

void BufferedSpdyFramer::UpdateHeaderEncoderTableSize(uint32_t value) {
  spdy_framer_.UpdateHeaderEncoderTableSize(value);
}

uint32_t BufferedSpdyFramer::header_encoder_table_size() const {
  return spdy_framer_.header_encoder_table_size();
}

BufferedSpdyFramer::ControlFrameFields::ControlFrameFields() = default;

}  // namespace net
