// Copyright 2014 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_QUIC_FLOW_CONTROLLER_H_
#define QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_

#include "net/third_party/quiche/src/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"

namespace quic {

namespace test {
class QuicFlowControllerPeer;
}  // namespace test

class QuicConnection;
class QuicSession;

// How much larger the session flow control window needs to be relative to any
// stream's flow control window.
const float kSessionFlowControlMultiplier = 1.5;

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

  // Ensures the flow control window is at least |window_size| and send out an
  // update frame if it is increased.
  virtual void EnsureWindowAtLeast(QuicByteCount window_size) = 0;
};

// QuicFlowController allows a QUIC stream or connection to perform flow
// control. The stream/connection owns a QuicFlowController which keeps track of
// bytes sent/received, can tell the owner if it is flow control blocked, and
// can send WINDOW_UPDATE or BLOCKED frames when needed.
class QUIC_EXPORT_PRIVATE QuicFlowController
    : public QuicFlowControllerInterface {
 public:
  QuicFlowController(QuicSession* session,
                     QuicStreamId id,
                     bool is_connection_flow_controller,
                     QuicStreamOffset send_window_offset,
                     QuicStreamOffset receive_window_offset,
                     QuicByteCount receive_window_size_limit,
                     bool should_auto_tune_receive_window,
                     QuicFlowControllerInterface* session_flow_controller);

  QuicFlowController(const QuicFlowController&) = delete;
  QuicFlowController(QuicFlowController&&) = default;
  QuicFlowController& operator=(const QuicFlowController&) = delete;

  ~QuicFlowController() override {}

  // Called when we see a new highest received byte offset from the peer, either
  // via a data frame or a RST.
  // Returns true if this call changes highest_received_byte_offset_, and false
  // in the case where |new_offset| is <= highest_received_byte_offset_.
  bool UpdateHighestReceivedOffset(QuicStreamOffset new_offset);

  // Called when bytes received from the peer are consumed locally. This may
  // trigger the sending of a WINDOW_UPDATE frame using |connection|.
  void AddBytesConsumed(QuicByteCount bytes_consumed);

  // Called when bytes are sent to the peer.
  void AddBytesSent(QuicByteCount bytes_sent);

  // Increases |send_window_offset_| if |new_send_window_offset| is
  // greater than the current value.  Returns true if this increase
  // also causes us to change from a blocked state to unblocked.  In
  // all other cases, returns false.
  bool UpdateSendWindowOffset(QuicStreamOffset new_send_window_offset);

  // QuicFlowControllerInterface.
  void EnsureWindowAtLeast(QuicByteCount window_size) override;

  // Returns the current available send window.
  QuicByteCount SendWindowSize() const;

  // Returns whether a BLOCKED frame should be sent.
  bool ShouldSendBlocked();

  // Returns true if flow control send limits have been reached.
  bool IsBlocked() const;

  // Returns true if flow control receive limits have been violated by the peer.
  bool FlowControlViolation();

  // Inform the peer of new receive window.
  void SendWindowUpdate();

  QuicByteCount bytes_consumed() const { return bytes_consumed_; }

  QuicStreamOffset highest_received_byte_offset() const {
    return highest_received_byte_offset_;
  }

  void set_receive_window_size_limit(QuicByteCount receive_window_size_limit) {
    DCHECK_GE(receive_window_size_limit, receive_window_size_limit_);
    receive_window_size_limit_ = receive_window_size_limit;
  }

  // Should only be called before any data is received.
  void UpdateReceiveWindowSize(QuicStreamOffset size);

  bool auto_tune_receive_window() { return auto_tune_receive_window_; }

 private:
  friend class test::QuicFlowControllerPeer;

  // Send a WINDOW_UPDATE frame if appropriate.
  void MaybeSendWindowUpdate();

  // Auto-tune the max receive window size.
  void MaybeIncreaseMaxWindowSize();

  // Updates the current offset and sends a window update frame.
  void UpdateReceiveWindowOffsetAndSendWindowUpdate(
      QuicStreamOffset available_window);

  // Double the window size as long as we haven't hit the max window size.
  void IncreaseWindowSize();

  // Returns "stream $ID" (where $ID is set to |id_|) or "connection" based on
  // |is_connection_flow_controller_|.
  std::string LogLabel();

  // The parent session/connection, used to send connection close on flow
  // control violation, and WINDOW_UPDATE and BLOCKED frames when appropriate.
  // Not owned.
  QuicSession* session_;
  QuicConnection* connection_;

  // ID of stream this flow controller belongs to. If
  // |is_connection_flow_controller_| is false, this must be a valid stream ID.
  QuicStreamId id_;

  // Whether this flow controller is the connection level flow controller
  // instead of the flow controller for a stream. If true, |id_| is ignored.
  bool is_connection_flow_controller_;

  // Tracks if this is owned by a server or a client.
  Perspective perspective_;

  // Tracks number of bytes sent to the peer.
  QuicByteCount bytes_sent_;

  // The absolute offset in the outgoing byte stream. If this offset is reached
  // then we become flow control blocked until we receive a WINDOW_UPDATE.
  QuicStreamOffset send_window_offset_;

  // Overview of receive flow controller.
  //
  // 0=...===1=======2-------3 ...... FIN
  //         |<--- <= 4  --->|
  //

  // 1) bytes_consumed_ - moves forward when data is read out of the
  //    stream.
  //
  // 2) highest_received_byte_offset_ - moves when data is received
  //    from the peer.
  //
  // 3) receive_window_offset_ - moves when WINDOW_UPDATE is sent.
  //
  // 4) receive_window_size_ - maximum allowed unread data (3 - 1).
  //    This value may be increased by auto-tuning.
  //
  // 5) receive_window_size_limit_ - limit on receive_window_size_;
  //    auto-tuning will not increase window size beyond this limit.

  // Track number of bytes received from the peer, which have been consumed
  // locally.
  QuicByteCount bytes_consumed_;

  // The highest byte offset we have seen from the peer. This could be the
  // highest offset in a data frame, or a final value in a RST.
  QuicStreamOffset highest_received_byte_offset_;

  // The absolute offset in the incoming byte stream. The peer should never send
  // us bytes which are beyond this offset.
  QuicStreamOffset receive_window_offset_;

  // Largest size the receive window can grow to.
  QuicByteCount receive_window_size_;

  // Upper limit on receive_window_size_;
  QuicByteCount receive_window_size_limit_;

  // Used to dynamically enable receive window auto-tuning.
  bool auto_tune_receive_window_;

  // The session's flow controller.  null if this is stream id 0.
  // Not owned.
  QuicFlowControllerInterface* session_flow_controller_;

  // Send window update when receive window size drops below this.
  QuicByteCount WindowUpdateThreshold();

  // Keep track of the last time we sent a BLOCKED frame. We should only send
  // another when the number of bytes we have sent has changed.
  QuicStreamOffset last_blocked_send_window_offset_;

  // Keep time of the last time a window update was sent.  We use this
  // as part of the receive window auto tuning.
  QuicTime prev_window_update_time_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_FLOW_CONTROLLER_H_
