// Copyright (c) 2018 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.

#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
#define QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_receiver.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_header_table.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_instructions.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"

namespace spdy {

class SpdyHeaderBlock;

}  // namespace spdy

namespace quic {

namespace test {

class QpackEncoderPeer;

}  // namespace test

// QPACK encoder class.  Exactly one instance should exist per QUIC connection.
class QUIC_EXPORT_PRIVATE QpackEncoder
    : public QpackDecoderStreamReceiver::Delegate {
 public:
  // Interface for receiving notification that an error has occurred on the
  // decoder stream.  This MUST be treated as a connection error of type
  // HTTP_QPACK_DECODER_STREAM_ERROR.
  class QUIC_EXPORT_PRIVATE DecoderStreamErrorDelegate {
   public:
    virtual ~DecoderStreamErrorDelegate() {}

    virtual void OnDecoderStreamError(
        quiche::QuicheStringPiece error_message) = 0;
  };

  QpackEncoder(DecoderStreamErrorDelegate* decoder_stream_error_delegate);
  ~QpackEncoder() override;

  // Encode a header list.  If |encoder_stream_sent_byte_count| is not null,
  // |*encoder_stream_sent_byte_count| will be set to the number of bytes sent
  // on the encoder stream to insert dynamic table entries.
  std::string EncodeHeaderList(QuicStreamId stream_id,
                               const spdy::SpdyHeaderBlock& header_list,
                               QuicByteCount* encoder_stream_sent_byte_count);

  // Set maximum dynamic table capacity to |maximum_dynamic_table_capacity|,
  // measured in bytes.  Called when SETTINGS_QPACK_MAX_TABLE_CAPACITY is
  // received.  Encoder needs to know this value so that it can calculate
  // MaxEntries, used as a modulus to encode Required Insert Count.
  // Returns true if |maximum_dynamic_table_capacity| is set for the first time
  // or if it doesn't change current value. The setting is not changed when
  // returning false.
  bool SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);

  // Set dynamic table capacity to |dynamic_table_capacity|.
  // |dynamic_table_capacity| must not exceed maximum dynamic table capacity.
  // Also sends Set Dynamic Table Capacity instruction on encoder stream.
  void SetDynamicTableCapacity(uint64_t dynamic_table_capacity);

  // Set maximum number of blocked streams.
  // Called when SETTINGS_QPACK_BLOCKED_STREAMS is received.
  // Returns true if |maximum_blocked_streams| doesn't decrease current value.
  // The setting is not changed when returning false.
  bool SetMaximumBlockedStreams(uint64_t maximum_blocked_streams);

  // QpackDecoderStreamReceiver::Delegate implementation
  void OnInsertCountIncrement(uint64_t increment) override;
  void OnHeaderAcknowledgement(QuicStreamId stream_id) override;
  void OnStreamCancellation(QuicStreamId stream_id) override;
  void OnErrorDetected(quiche::QuicheStringPiece error_message) override;

  // delegate must be set if dynamic table capacity is not zero.
  void set_qpack_stream_sender_delegate(QpackStreamSenderDelegate* delegate) {
    encoder_stream_sender_.set_qpack_stream_sender_delegate(delegate);
  }

  QpackStreamReceiver* decoder_stream_receiver() {
    return &decoder_stream_receiver_;
  }

  // True if any dynamic table entries have been referenced from a header block.
  bool dynamic_table_entry_referenced() const {
    return header_table_.dynamic_table_entry_referenced();
  }

  uint64_t maximum_blocked_streams() const { return maximum_blocked_streams_; }

  uint64_t MaximumDynamicTableCapacity() const {
    return header_table_.maximum_dynamic_table_capacity();
  }

 private:
  friend class test::QpackEncoderPeer;

  using Instructions = std::vector<QpackInstructionWithValues>;

  // Generate indexed header field instruction
  // and optionally update |*referred_indices|.
  static QpackInstructionWithValues EncodeIndexedHeaderField(
      bool is_static,
      uint64_t index,
      QpackBlockingManager::IndexSet* referred_indices);

  // Generate literal header field with name reference instruction
  // and optionally update |*referred_indices|.
  static QpackInstructionWithValues EncodeLiteralHeaderFieldWithNameReference(
      bool is_static,
      uint64_t index,
      quiche::QuicheStringPiece value,
      QpackBlockingManager::IndexSet* referred_indices);

  // Generate literal header field instruction.
  static QpackInstructionWithValues EncodeLiteralHeaderField(
      quiche::QuicheStringPiece name,
      quiche::QuicheStringPiece value);

  // Performs first pass of two-pass encoding: represent each header field in
  // |*header_list| as a reference to an existing entry, the name of an existing
  // entry with a literal value, or a literal name and value pair.  Sends
  // necessary instructions on the encoder stream coalesced in a single write.
  // Records absolute indices of referred dynamic table entries in
  // |*referred_indices|.  If |encoder_stream_sent_byte_count| is not null, then
  // sets |*encoder_stream_sent_byte_count| to the number of bytes sent on the
  // encoder stream to insert dynamic table entries.  Returns list of header
  // field representations, with all dynamic table entries referred to with
  // absolute indices.  Returned Instructions object may have
  // quiche::QuicheStringPieces pointing to strings owned by |*header_list|.
  Instructions FirstPassEncode(QuicStreamId stream_id,
                               const spdy::SpdyHeaderBlock& header_list,
                               QpackBlockingManager::IndexSet* referred_indices,
                               QuicByteCount* encoder_stream_sent_byte_count);

  // Performs second pass of two-pass encoding: serializes representations
  // generated in first pass, transforming absolute indices of dynamic table
  // entries to relative indices.
  std::string SecondPassEncode(Instructions instructions,
                               uint64_t required_insert_count) const;

  DecoderStreamErrorDelegate* const decoder_stream_error_delegate_;
  QpackDecoderStreamReceiver decoder_stream_receiver_;
  QpackEncoderStreamSender encoder_stream_sender_;
  QpackHeaderTable header_table_;
  uint64_t maximum_blocked_streams_;
  QpackBlockingManager blocking_manager_;
  int header_list_count_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_ENCODER_H_
