// 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.

#ifndef NET_SPDY_BUFFERED_SPDY_FRAMER_H_
#define NET_SPDY_BUFFERED_SPDY_FRAMER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>

#include "base/memory/raw_ptr.h"
#include "base/strings/string_piece.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/log/net_log_source.h"
#include "net/spdy/header_coalescer.h"
#include "net/third_party/quiche/src/quiche/spdy/core/http2_frame_decoder_adapter.h"
#include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
#include "net/third_party/quiche/src/quiche/spdy/core/spdy_alt_svc_wire_format.h"
#include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
#include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"

namespace net {

class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
 public:
  BufferedSpdyFramerVisitorInterface() = default;

  BufferedSpdyFramerVisitorInterface(
      const BufferedSpdyFramerVisitorInterface&) = delete;
  BufferedSpdyFramerVisitorInterface& operator=(
      const BufferedSpdyFramerVisitorInterface&) = delete;

  // Called if an error is detected in the spdy::SpdySerializedFrame protocol.
  virtual void OnError(
      http2::Http2DecoderAdapter::SpdyFramerError spdy_framer_error) = 0;

  // Called if an error is detected in a HTTP2 stream.
  virtual void OnStreamError(spdy::SpdyStreamId stream_id,
                             const std::string& description) = 0;

  // Called after all the header data for HEADERS control frame is received.
  virtual void OnHeaders(spdy::SpdyStreamId stream_id,
                         bool has_priority,
                         int weight,
                         spdy::SpdyStreamId parent_stream_id,
                         bool exclusive,
                         bool fin,
                         spdy::Http2HeaderBlock headers,
                         base::TimeTicks recv_first_byte_time) = 0;

  // Called when a data frame header is received.
  virtual void OnDataFrameHeader(spdy::SpdyStreamId stream_id,
                                 size_t length,
                                 bool fin) = 0;

  // Called when data is received.
  // |stream_id| The stream receiving data.
  // |data| A buffer containing the data received.
  // |len| The length of the data buffer (at most 2^16 - 1 - 8).
  virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
                                 const char* data,
                                 size_t len) = 0;

  // Called when the other side has finished sending data on this stream.
  // |stream_id| The stream that was receivin data.
  virtual void OnStreamEnd(spdy::SpdyStreamId stream_id) = 0;

  // Called when padding is received (padding length field or padding octets).
  // |stream_id| The stream receiving data.
  // |len| The number of padding octets.
  virtual void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) = 0;

  // Called when a SETTINGS frame is received.
  virtual void OnSettings() = 0;

  // Called when an individual setting within a SETTINGS frame has been parsed.
  // Note that |id| may or may not be a SETTINGS ID defined in the HTTP/2 spec.
  virtual void OnSetting(spdy::SpdySettingsId id, uint32_t value) = 0;

  // Called when a SETTINGS frame is received with the ACK flag set.
  virtual void OnSettingsAck() = 0;

  // Called at the completion of parsing SETTINGS id and value tuples.
  virtual void OnSettingsEnd() = 0;

  // Called when a PING frame has been parsed.
  virtual void OnPing(spdy::SpdyPingId unique_id, bool is_ack) = 0;

  // Called when a RST_STREAM frame has been parsed.
  virtual void OnRstStream(spdy::SpdyStreamId stream_id,
                           spdy::SpdyErrorCode error_code) = 0;

  // Called when a GOAWAY frame has been parsed.
  virtual void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
                        spdy::SpdyErrorCode error_code,
                        base::StringPiece debug_data) = 0;

  // Called when a WINDOW_UPDATE frame has been parsed.
  virtual void OnWindowUpdate(spdy::SpdyStreamId stream_id,
                              int delta_window_size) = 0;

  // Called when a PUSH_PROMISE frame has been parsed.
  virtual void OnPushPromise(spdy::SpdyStreamId stream_id,
                             spdy::SpdyStreamId promised_stream_id,
                             spdy::Http2HeaderBlock headers) = 0;

  // Called when an ALTSVC frame has been parsed.
  virtual void OnAltSvc(
      spdy::SpdyStreamId stream_id,
      base::StringPiece origin,
      const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector&
          altsvc_vector) = 0;

  // Called when a frame type we don't recognize is received.
  // Return true if this appears to be a valid extension frame, false otherwise.
  // We distinguish between extension frames and nonsense by checking
  // whether the stream id is valid.
  virtual bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
                              uint8_t frame_type) = 0;

 protected:
  virtual ~BufferedSpdyFramerVisitorInterface() = default;
};

class NET_EXPORT_PRIVATE BufferedSpdyFramer
    : public spdy::SpdyFramerVisitorInterface {
 public:
  using TimeFunc = base::TimeTicks (*)();

  BufferedSpdyFramer(uint32_t max_header_list_size,
                     const NetLogWithSource& net_log,
                     TimeFunc time_func = base::TimeTicks::Now);
  BufferedSpdyFramer() = delete;

  BufferedSpdyFramer(const BufferedSpdyFramer&) = delete;
  BufferedSpdyFramer& operator=(const BufferedSpdyFramer&) = delete;

  ~BufferedSpdyFramer() override;

  // Sets callbacks to be called from the buffered spdy framer.  A visitor must
  // be set, or else the framer will likely crash.  It is acceptable for the
  // visitor to do nothing.  If this is called multiple times, only the last
  // visitor will be used.
  void set_visitor(BufferedSpdyFramerVisitorInterface* visitor);

  // Set debug callbacks to be called from the framer. The debug visitor is
  // completely optional and need not be set in order for normal operation.
  // If this is called multiple times, only the last visitor will be used.
  void set_debug_visitor(spdy::SpdyFramerDebugVisitorInterface* debug_visitor);

  // spdy::SpdyFramerVisitorInterface
  void OnError(http2::Http2DecoderAdapter::SpdyFramerError spdy_framer_error,
               std::string detailed_error) override;
  void 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) override;
  void OnStreamFrameData(spdy::SpdyStreamId stream_id,
                         const char* data,
                         size_t len) override;
  void OnStreamEnd(spdy::SpdyStreamId stream_id) override;
  void OnStreamPadLength(spdy::SpdyStreamId stream_id, size_t value) override;
  void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) override;
  spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
      spdy::SpdyStreamId stream_id) override;
  void OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) override;
  void OnSettings() override;
  void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
  void OnSettingsAck() override;
  void OnSettingsEnd() override;
  void OnPing(spdy::SpdyPingId unique_id, bool is_ack) override;
  void OnRstStream(spdy::SpdyStreamId stream_id,
                   spdy::SpdyErrorCode error_code) override;
  void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
                spdy::SpdyErrorCode error_code) override;
  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
  void OnWindowUpdate(spdy::SpdyStreamId stream_id,
                      int delta_window_size) override;
  void OnPushPromise(spdy::SpdyStreamId stream_id,
                     spdy::SpdyStreamId promised_stream_id,
                     bool end) override;
  void OnAltSvc(spdy::SpdyStreamId stream_id,
                absl::string_view origin,
                const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector&
                    altsvc_vector) override;
  void OnDataFrameHeader(spdy::SpdyStreamId stream_id,
                         size_t length,
                         bool fin) override;
  void OnContinuation(spdy::SpdyStreamId stream_id,
                      size_t payload_length,
                      bool end) override;
  void OnPriority(spdy::SpdyStreamId stream_id,
                  spdy::SpdyStreamId parent_stream_id,
                  int weight,
                  bool exclusive) override {}
  void OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
                        absl::string_view priority_field_value) override {}
  bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
                      uint8_t frame_type) override;
  void OnUnknownFrameStart(spdy::SpdyStreamId stream_id,
                           size_t length,
                           uint8_t type,
                           uint8_t flags) override {}
  void OnUnknownFramePayload(spdy::SpdyStreamId stream_id,
                             absl::string_view payload) override {}

  // spdy::SpdyFramer methods.
  size_t ProcessInput(const char* data, size_t len);
  void UpdateHeaderDecoderTableSize(uint32_t value);
  http2::Http2DecoderAdapter::SpdyFramerError spdy_framer_error() const;
  http2::Http2DecoderAdapter::SpdyState state() const;
  bool MessageFullyRead();
  bool HasError();
  std::unique_ptr<spdy::SpdySerializedFrame> CreateRstStream(
      spdy::SpdyStreamId stream_id,
      spdy::SpdyErrorCode error_code) const;
  std::unique_ptr<spdy::SpdySerializedFrame> CreateSettings(
      const spdy::SettingsMap& values) const;
  std::unique_ptr<spdy::SpdySerializedFrame> CreatePingFrame(
      spdy::SpdyPingId unique_id,
      bool is_ack) const;
  std::unique_ptr<spdy::SpdySerializedFrame> CreateWindowUpdate(
      spdy::SpdyStreamId stream_id,
      uint32_t delta_window_size) const;
  std::unique_ptr<spdy::SpdySerializedFrame> CreateDataFrame(
      spdy::SpdyStreamId stream_id,
      const char* data,
      uint32_t len,
      spdy::SpdyDataFlags flags);
  std::unique_ptr<spdy::SpdySerializedFrame> CreatePriority(
      spdy::SpdyStreamId stream_id,
      spdy::SpdyStreamId dependency_id,
      int weight,
      bool exclusive) const;

  // Serialize a frame of unknown type.
  spdy::SpdySerializedFrame SerializeFrame(const spdy::SpdyFrameIR& frame) {
    return spdy_framer_.SerializeFrame(frame);
  }

  int frames_received() const { return frames_received_; }

  // Updates the maximum size of the header encoder compression table.
  void UpdateHeaderEncoderTableSize(uint32_t value);
  // Returns the maximum size of the header encoder compression table.
  uint32_t header_encoder_table_size() const;

 private:
  spdy::SpdyFramer spdy_framer_;
  http2::Http2DecoderAdapter deframer_;
  raw_ptr<BufferedSpdyFramerVisitorInterface> visitor_ = nullptr;

  int frames_received_ = 0;

  // Collection of fields from control frames that we need to
  // buffer up from the spdy framer.
  struct ControlFrameFields {
    ControlFrameFields();

    spdy::SpdyFrameType type;
    spdy::SpdyStreamId stream_id = 0U;
    spdy::SpdyStreamId associated_stream_id = 0U;
    spdy::SpdyStreamId promised_stream_id = 0U;
    bool has_priority = false;
    spdy::SpdyPriority priority = 0U;
    int weight = 0;
    spdy::SpdyStreamId parent_stream_id = 0U;
    bool exclusive = false;
    bool fin = false;
    bool unidirectional = false;
    base::TimeTicks recv_first_byte_time;
  };
  std::unique_ptr<ControlFrameFields> control_frame_fields_;

  // Collection of fields of a GOAWAY frame that this class needs to buffer.
  struct GoAwayFields {
    spdy::SpdyStreamId last_accepted_stream_id;
    spdy::SpdyErrorCode error_code;
    std::string debug_data;
  };
  std::unique_ptr<GoAwayFields> goaway_fields_;

  std::unique_ptr<HeaderCoalescer> coalescer_;

  const uint32_t max_header_list_size_;
  NetLogWithSource net_log_;
  TimeFunc time_func_;
};

}  // namespace net

#endif  // NET_SPDY_BUFFERED_SPDY_FRAMER_H_
