// 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.
//
// Accumulates frames for the next packet until more frames no longer fit or
// it's time to create a packet from them.  Also provides packet creation of
// FEC packets based on previously created packets.

#ifndef NET_QUIC_QUIC_PACKET_CREATOR_H_
#define NET_QUIC_QUIC_PACKET_CREATOR_H_

#include <utility>
#include <vector>

#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/quic/quic_fec_group.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_protocol.h"

namespace net {
namespace test {
class QuicPacketCreatorPeer;
}

class QuicAckNotifier;
class QuicRandom;
class QuicRandomBoolSource;

class NET_EXPORT_PRIVATE QuicPacketCreator : public QuicFecBuilderInterface {
 public:
  // QuicRandom* required for packet entropy.
  QuicPacketCreator(QuicConnectionId connection_id,
                    QuicFramer* framer,
                    QuicRandom* random_generator);

  virtual ~QuicPacketCreator();

  // QuicFecBuilderInterface
  virtual void OnBuiltFecProtectedPayload(const QuicPacketHeader& header,
                                          base::StringPiece payload) OVERRIDE;

  // Turn on FEC protection for subsequently created packets. FEC should be
  // enabled first (max_packets_per_fec_group should be non-zero) for FEC
  // protection to start.
  void StartFecProtectingPackets();

  // Turn off FEC protection for subsequently created packets. If the creator
  // has any open FEC group, call will fail. It is the caller's responsibility
  // to flush out FEC packets in generation, and to verify with ShouldSendFec()
  // that there is no open FEC group.
  void StopFecProtectingPackets();

  // Checks if it's time to send an FEC packet.  |force_close| forces this to
  // return true if an FEC group is open.
  bool ShouldSendFec(bool force_close) const;

  // Returns true if an FEC packet is under construction.
  bool IsFecGroupOpen() const;

  // Makes the framer not serialize the protocol version in sent packets.
  void StopSendingVersion();

  // Update the sequence number length to use in future packets as soon as it
  // can be safely changed.
  void UpdateSequenceNumberLength(
      QuicPacketSequenceNumber least_packet_awaited_by_peer,
      QuicByteCount congestion_window);

  // The overhead the framing will add for a packet with one frame.
  static size_t StreamFramePacketOverhead(
      QuicConnectionIdLength connection_id_length,
      bool include_version,
      QuicSequenceNumberLength sequence_number_length,
      QuicStreamOffset offset,
      InFecGroup is_in_fec_group);

  bool HasRoomForStreamFrame(QuicStreamId id, QuicStreamOffset offset) const;

  // Converts a raw payload to a frame which fits into the currently open
  // packet if there is one.  Returns the number of bytes consumed from data.
  // If data is empty and fin is true, the expected behavior is to consume the
  // fin but return 0.
  size_t CreateStreamFrame(QuicStreamId id,
                           const IOVector& data,
                           QuicStreamOffset offset,
                           bool fin,
                           QuicFrame* frame);

  // As above, but keeps track of an QuicAckNotifier that should be called when
  // the packet that contains this stream frame is ACKed.
  // The |notifier| is not owned by the QuicPacketGenerator and must outlive the
  // generated packet.
  size_t CreateStreamFrameWithNotifier(QuicStreamId id,
                                       const IOVector& data,
                                       QuicStreamOffset offset,
                                       bool fin,
                                       QuicAckNotifier* notifier,
                                       QuicFrame* frame);

  // Serializes all frames into a single packet. All frames must fit into a
  // single packet. Also, sets the entropy hash of the serialized packet to a
  // random bool and returns that value as a member of SerializedPacket.
  // Never returns a RetransmittableFrames in SerializedPacket.
  SerializedPacket SerializeAllFrames(const QuicFrames& frames);

  // Re-serializes frames with the original packet's sequence number length.
  // Used for retransmitting packets to ensure they aren't too long.
  // Caller must ensure that any open FEC group is closed before calling this
  // method.
  SerializedPacket ReserializeAllFrames(
      const QuicFrames& frames,
      QuicSequenceNumberLength original_length);

  // Returns true if there are frames pending to be serialized.
  bool HasPendingFrames() const;

  // Returns true if there are retransmittable frames pending to be serialized.
  bool HasPendingRetransmittableFrames() const;

  // Returns whether FEC protection is currently enabled. Note: Enabled does not
  // mean that an FEC group is currently active; i.e., IsFecProtected() may
  // still return false.
  bool IsFecEnabled() const;

  // Returns true if subsequent packets will be FEC protected. Note: True does
  // not mean that an FEC packet is currently under construction; i.e.,
  // fec_group_.get() may still be NULL, until MaybeStartFec() is called.
  bool IsFecProtected() const;

  // Returns the number of bytes which are available to be used by additional
  // frames in the packet.  Since stream frames are slightly smaller when they
  // are the last frame in a packet, this method will return a different
  // value than max_packet_size - PacketSize(), in this case.
  size_t BytesFree() const;

  // Returns the number of bytes that the packet will expand by if a new frame
  // is added to the packet. If the last frame was a stream frame, it will
  // expand slightly when a new frame is added, and this method returns the
  // amount of expected expansion. If the packet is in an FEC group, no
  // expansion happens and this method always returns zero.
  size_t ExpansionOnNewFrame() const;

  // Returns the number of bytes in the current packet, including the header,
  // if serialized with the current frames.  Adding a frame to the packet
  // may change the serialized length of existing frames, as per the comment
  // in BytesFree.
  size_t PacketSize() const;

  // TODO(jri): AddSavedFrame calls AddFrame, which only saves the frame
  // if it is a stream frame, not other types of frames. Fix this API;
  // add a AddNonSavedFrame method.
  // Adds |frame| to the packet creator's list of frames to be serialized.
  // Returns false if the frame doesn't fit into the current packet.
  bool AddSavedFrame(const QuicFrame& frame);

  // Serializes all frames which have been added and adds any which should be
  // retransmitted to |retransmittable_frames| if it's not NULL. All frames must
  // fit into a single packet. Sets the entropy hash of the serialized
  // packet to a random bool and returns that value as a member of
  // SerializedPacket. Also, sets |serialized_frames| in the SerializedPacket
  // to the corresponding RetransmittableFrames if any frames are to be
  // retransmitted.
  SerializedPacket SerializePacket();

  // Packetize FEC data. All frames must fit into a single packet. Also, sets
  // the entropy hash of the serialized packet to a random bool and returns
  // that value as a member of SerializedPacket.
  SerializedPacket SerializeFec();

  // Creates a packet with connection close frame. Caller owns the created
  // packet. Also, sets the entropy hash of the serialized packet to a random
  // bool and returns that value as a member of SerializedPacket.
  SerializedPacket SerializeConnectionClose(
      QuicConnectionCloseFrame* close_frame);

  // Creates a version negotiation packet which supports |supported_versions|.
  // Caller owns the created  packet. Also, sets the entropy hash of the
  // serialized packet to a random bool and returns that value as a member of
  // SerializedPacket.
  QuicEncryptedPacket* SerializeVersionNegotiationPacket(
      const QuicVersionVector& supported_versions);

  // Sets the encryption level that will be applied to new packets.
  void set_encryption_level(EncryptionLevel level) {
    encryption_level_ = level;
  }

  // Sequence number of the last created packet, or 0 if no packets have been
  // created.
  QuicPacketSequenceNumber sequence_number() const {
    return sequence_number_;
  }

  void set_sequence_number(QuicPacketSequenceNumber s) {
    sequence_number_ = s;
  }

  QuicConnectionIdLength connection_id_length() const {
    return connection_id_length_;
  }

  QuicSequenceNumberLength next_sequence_number_length() const {
    return next_sequence_number_length_;
  }

  void set_next_sequence_number_length(QuicSequenceNumberLength length) {
    next_sequence_number_length_ = length;
  }

  size_t max_packet_length() const {
    return max_packet_length_;
  }

  void set_max_packet_length(size_t length) {
    // |max_packet_length_| should not be changed mid-packet or mid-FEC group.
    DCHECK(fec_group_.get() == NULL && queued_frames_.empty());
    max_packet_length_ = length;
  }

  // Returns current max number of packets covered by an FEC group.
  size_t max_packets_per_fec_group() const {
      return max_packets_per_fec_group_;
  }

  // Sets creator's max number of packets covered by an FEC group.
  // Note: While there are no constraints on |max_packets_per_fec_group|,
  // this setter enforces a min value of kLowestMaxPacketsPerFecGroup.
  // To turn off FEC protection, use StopFecProtectingPackets().
  void set_max_packets_per_fec_group(size_t max_packets_per_fec_group);

 private:
  friend class test::QuicPacketCreatorPeer;

  static bool ShouldRetransmit(const QuicFrame& frame);

  // Updates sequence number and max packet lengths on a packet or FEC group
  // boundary.
  void MaybeUpdateLengths();

  // Updates lengths and also starts an FEC group if FEC protection is on and
  // there is not already an FEC group open.
  InFecGroup MaybeUpdateLengthsAndStartFec();

  void FillPacketHeader(QuicFecGroupNumber fec_group,
                        bool fec_flag,
                        QuicPacketHeader* header);

  // Allows a frame to be added without creating retransmittable frames.
  // Particularly useful for retransmits using SerializeAllFrames().
  bool AddFrame(const QuicFrame& frame, bool save_retransmittable_frames);

  // Adds a padding frame to the current packet only if the current packet
  // contains a handshake message, and there is sufficient room to fit a
  // padding frame.
  void MaybeAddPadding();

  QuicConnectionId connection_id_;
  EncryptionLevel encryption_level_;
  QuicFramer* framer_;
  scoped_ptr<QuicRandomBoolSource> random_bool_source_;
  QuicPacketSequenceNumber sequence_number_;
  // If true, any created packets will be FEC protected.
  bool should_fec_protect_;
  QuicFecGroupNumber fec_group_number_;
  scoped_ptr<QuicFecGroup> fec_group_;
  // Controls whether protocol version should be included while serializing the
  // packet.
  bool send_version_in_packet_;
  // Maximum length including headers and encryption (UDP payload length.)
  size_t max_packet_length_;
  // 0 indicates FEC is disabled.
  size_t max_packets_per_fec_group_;
  // Length of connection_id to send over the wire.
  QuicConnectionIdLength connection_id_length_;
  // Staging variable to hold next packet sequence number length. When sequence
  // number length is to be changed, this variable holds the new length until
  // a packet or FEC group boundary, when the creator's sequence_number_length_
  // can be changed to this new value.
  QuicSequenceNumberLength next_sequence_number_length_;
  // Sequence number length for the current packet and for the current FEC group
  // when FEC is enabled. Mutable so PacketSize() can adjust it when the packet
  // is empty.
  mutable QuicSequenceNumberLength sequence_number_length_;
  // packet_size_ is mutable because it's just a cache of the current size.
  // packet_size should never be read directly, use PacketSize() instead.
  mutable size_t packet_size_;
  QuicFrames queued_frames_;
  scoped_ptr<RetransmittableFrames> queued_retransmittable_frames_;

  DISALLOW_COPY_AND_ASSIGN(QuicPacketCreator);
};

}  // namespace net

#endif  // NET_QUIC_QUIC_PACKET_CREATOR_H_
