// Copyright (c) 2012 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_CRYPTO_CRYPTO_FRAMER_H_
#define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_

#include <cstddef>
#include <cstdint>
#include <memory>
#include <utility>
#include <vector>

#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
#include "net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h"
#include "net/third_party/quiche/src/quic/core/quic_packets.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 CryptoFramer;
class QuicData;
class QuicDataWriter;

class QUIC_EXPORT_PRIVATE CryptoFramerVisitorInterface {
 public:
  virtual ~CryptoFramerVisitorInterface() {}

  // Called if an error is detected.
  virtual void OnError(CryptoFramer* framer) = 0;

  // Called when a complete handshake message has been parsed.
  virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0;
};

// A class for framing the crypto messages that are exchanged in a QUIC
// session.
class QUIC_EXPORT_PRIVATE CryptoFramer : public CryptoMessageParser {
 public:
  CryptoFramer();

  ~CryptoFramer() override;

  // ParseMessage parses exactly one message from the given QuicStringPiece. If
  // there is an error, the message is truncated, or the message has trailing
  // garbage then nullptr will be returned.
  static std::unique_ptr<CryptoHandshakeMessage> ParseMessage(
      QuicStringPiece in);

  // Set callbacks to be called from the framer.  A visitor must be set, or
  // else the framer will crash.  It is acceptable for the visitor to do
  // nothing.  If this is called multiple times, only the last visitor
  // will be used.  |visitor| will be owned by the framer.
  void set_visitor(CryptoFramerVisitorInterface* visitor) {
    visitor_ = visitor;
  }

  QuicErrorCode error() const override;
  const std::string& error_detail() const override;

  // Processes input data, which must be delivered in order. Returns
  // false if there was an error, and true otherwise. ProcessInput optionally
  // takes an EncryptionLevel, but it is ignored. The variant with the
  // EncryptionLevel is provided to match the CryptoMessageParser interface.
  bool ProcessInput(QuicStringPiece input, EncryptionLevel level) override;
  bool ProcessInput(QuicStringPiece input);

  // Returns the number of bytes of buffered input data remaining to be
  // parsed.
  size_t InputBytesRemaining() const override;

  // Checks if the specified tag has been seen. Returns |true| if it
  // has, and |false| if it has not or a CHLO has not been seen.
  bool HasTag(QuicTag tag) const;

  // Even if the CHLO has not been fully received, force processing of
  // the handshake message. This is dangerous and should not be used
  // except as a mechanism of last resort.
  void ForceHandshake();

  // Returns a new QuicData owned by the caller that contains a serialized
  // |message|, or nullptr if there was an error.
  static QuicData* ConstructHandshakeMessage(
      const CryptoHandshakeMessage& message);

  // Debug only method which permits processing truncated messages.
  void set_process_truncated_messages(bool process_truncated_messages) {
    process_truncated_messages_ = process_truncated_messages;
  }

 private:
  // Clears per-message state.  Does not clear the visitor.
  void Clear();

  // Process does does the work of |ProcessInput|, but returns an error code,
  // doesn't set error_ and doesn't call |visitor_->OnError()|.
  QuicErrorCode Process(QuicStringPiece input);

  static bool WritePadTag(QuicDataWriter* writer,
                          size_t pad_length,
                          uint32_t* end_offset);

  // Represents the current state of the parsing state machine.
  enum CryptoFramerState {
    STATE_READING_TAG,
    STATE_READING_NUM_ENTRIES,
    STATE_READING_TAGS_AND_LENGTHS,
    STATE_READING_VALUES
  };

  // Visitor to invoke when messages are parsed.
  CryptoFramerVisitorInterface* visitor_;
  // Last error.
  QuicErrorCode error_;
  // Remaining unparsed data.
  std::string buffer_;
  // Current state of the parsing.
  CryptoFramerState state_;
  // The message currently being parsed.
  CryptoHandshakeMessage message_;
  // The issue which caused |error_|
  std::string error_detail_;
  // Number of entires in the message currently being parsed.
  uint16_t num_entries_;
  // tags_and_lengths_ contains the tags that are currently being parsed and
  // their lengths.
  std::vector<std::pair<QuicTag, size_t>> tags_and_lengths_;
  // Cumulative length of all values in the message currently being parsed.
  size_t values_len_;
  // Set to true to allow of processing of truncated messages for debugging.
  bool process_truncated_messages_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
