// 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_PROGRESSIVE_DECODER_H_
#define QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_

#include <cstdint>
#include <memory>

#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_receiver.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_decoder.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_string.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"

namespace quic {

class QpackHeaderTable;

// Class to decode a single header block.
class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder
    : public QpackInstructionDecoder::Delegate {
 public:
  // Interface for receiving decoded header block from the decoder.
  class QUIC_EXPORT_PRIVATE HeadersHandlerInterface {
   public:
    virtual ~HeadersHandlerInterface() {}

    // Called when a new header name-value pair is decoded.  Multiple values for
    // a given name will be emitted as multiple calls to OnHeader.
    virtual void OnHeaderDecoded(QuicStringPiece name,
                                 QuicStringPiece value) = 0;

    // Called when the header block is completely decoded.
    // Indicates the total number of bytes in this block.
    // The decoder will not access the handler after this call.
    // Note that this method might not be called synchronously when the header
    // block is received on the wire, in case decoding is blocked on receiving
    // entries on the encoder stream.  TODO(bnc): Implement blocked decoding.
    virtual void OnDecodingCompleted() = 0;

    // Called when a decoding error has occurred.  No other methods will be
    // called afterwards.
    virtual void OnDecodingErrorDetected(QuicStringPiece error_message) = 0;
  };

  QpackProgressiveDecoder() = delete;
  QpackProgressiveDecoder(QuicStreamId stream_id,
                          QpackHeaderTable* header_table,
                          QpackDecoderStreamSender* decoder_stream_sender,
                          HeadersHandlerInterface* handler);
  QpackProgressiveDecoder(const QpackProgressiveDecoder&) = delete;
  QpackProgressiveDecoder& operator=(const QpackProgressiveDecoder&) = delete;
  ~QpackProgressiveDecoder() override = default;

  // Calculate actual Largest Reference from largest reference value sent on
  // wire, MaxEntries, and total number of dynamic table insertions according to
  // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#largest-reference
  // Returns true on success, false on invalid input or overflow/underflow.
  static bool DecodeLargestReference(uint64_t wire_largest_reference,
                                     uint64_t max_entries,
                                     uint64_t total_number_of_inserts,
                                     uint64_t* largest_reference);

  // Provide a data fragment to decode.
  void Decode(QuicStringPiece data);

  // Signal that the entire header block has been received and passed in
  // through Decode().  No methods must be called afterwards.
  void EndHeaderBlock();

  // QpackInstructionDecoder::Delegate implementation.
  bool OnInstructionDecoded(const QpackInstruction* instruction) override;
  void OnError(QuicStringPiece error_message) override;

 private:
  bool DoIndexedHeaderFieldInstruction();
  bool DoIndexedHeaderFieldPostBaseInstruction();
  bool DoLiteralHeaderFieldNameReferenceInstruction();
  bool DoLiteralHeaderFieldPostBaseInstruction();
  bool DoLiteralHeaderFieldInstruction();
  bool DoPrefixInstruction();

  // Calculates Base Index from |largest_reference_|, which must be set before
  // calling this method, and sign bit and Delta Base Index in the Header Data
  // Prefix, which are passed in as arguments.  Returns true on success, false
  // on failure due to overflow/underflow.
  bool DeltaBaseIndexToBaseIndex(bool sign,
                                 uint64_t delta_base_index,
                                 uint64_t* base_index);

  // The request stream can use relative index (but different from the kind of
  // relative index used on the encoder stream), and post-base index.
  // These methods convert relative index and post-base index to absolute index
  // (one based).  They return true on success, or false if conversion fails due
  // to overflow/underflow.
  bool RequestStreamRelativeIndexToAbsoluteIndex(
      uint64_t relative_index,
      uint64_t* absolute_index) const;
  bool PostBaseIndexToAbsoluteIndex(uint64_t post_base_index,
                                    uint64_t* absolute_index) const;

  const QuicStreamId stream_id_;

  // |prefix_decoder_| only decodes a handful of bytes then it can be
  // destroyed to conserve memory.  |instruction_decoder_|, on the other hand,
  // is used until the entire header block is decoded.
  std::unique_ptr<QpackInstructionDecoder> prefix_decoder_;
  QpackInstructionDecoder instruction_decoder_;

  const QpackHeaderTable* const header_table_;
  QpackDecoderStreamSender* const decoder_stream_sender_;
  HeadersHandlerInterface* const handler_;

  // Largest Reference and Base Index are parsed from the Header Data Prefix.
  // They are both absolute indices, that is, one based.
  uint64_t largest_reference_;
  uint64_t base_index_;

  // Keep track of largest reference seen in this header block.
  // After decoding is completed, this can be compared to |largest_reference_|.
  uint64_t largest_reference_seen_;

  // False until prefix is fully read and decoded.
  bool prefix_decoded_;

  // True until EndHeaderBlock() is called.
  bool decoding_;

  // True if a decoding error has been detected.
  bool error_detected_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_PROGRESSIVE_DECODER_H_
