// 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_QUIC_STREAM_ID_MANAGER_H_
#define QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_

#include "net/third_party/quiche/src/quic/core/frames/quic_frame.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"

namespace quic {

namespace test {
class QuicSessionPeer;
class QuicStreamIdManagerPeer;
}  // namespace test

// This class manages the stream ids for IETF QUIC.
class QUIC_EXPORT_PRIVATE QuicStreamIdManager {
 public:
  class QUIC_EXPORT_PRIVATE DelegateInterface {
   public:
    virtual ~DelegateInterface() = default;

    // Send a MAX_STREAMS frame.
    virtual void SendMaxStreams(QuicStreamCount stream_count,
                                bool unidirectional) = 0;
  };

  QuicStreamIdManager(DelegateInterface* delegate,
                      bool unidirectional,
                      Perspective perspective,
                      ParsedQuicVersion version,
                      QuicStreamCount max_allowed_outgoing_streams,
                      QuicStreamCount max_allowed_incoming_streams);

  ~QuicStreamIdManager();

  // Generate a string suitable for sending to the log/etc to show current state
  // of the stream ID manager.
  std::string DebugString() const {
    return quiche::QuicheStrCat(
        " { unidirectional_: ", unidirectional_,
        ", perspective: ", perspective_,
        ", outgoing_max_streams_: ", outgoing_max_streams_,
        ", next_outgoing_stream_id_: ", next_outgoing_stream_id_,
        ", outgoing_stream_count_: ", outgoing_stream_count_,
        ", incoming_actual_max_streams_: ", incoming_actual_max_streams_,
        ", incoming_advertised_max_streams_: ",
        incoming_advertised_max_streams_,
        ", incoming_stream_count_: ", incoming_stream_count_,
        ", available_streams_.size(): ", available_streams_.size(),
        ", largest_peer_created_stream_id_: ", largest_peer_created_stream_id_,
        " }");
  }

  // Processes the STREAMS_BLOCKED frame. If error is encountered, populates
  // |error_details| and returns false.
  bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame,
                             std::string* error_details);

  // Returns whether the next outgoing stream ID can be allocated or not.
  bool CanOpenNextOutgoingStream() const;

  // Generate and send a MAX_STREAMS frame.
  void SendMaxStreamsFrame();

  // Invoked to deal with releasing a stream. Does nothing if the stream is
  // outgoing. If the stream is incoming, the number of streams that the peer
  // can open will be updated and a MAX_STREAMS frame, informing the peer of
  // the additional streams, may be sent.
  void OnStreamClosed(QuicStreamId stream_id);

  // Returns the next outgoing stream id. Applications must call
  // CanOpenNextOutgoingStream() first.
  QuicStreamId GetNextOutgoingStreamId();

  void SetMaxOpenIncomingStreams(QuicStreamCount max_open_streams);

  // Called on |max_open_streams| outgoing streams can be created because of 1)
  // config negotiated or 2) MAX_STREAMS received. Returns true if new
  // streams can be created.
  bool MaybeAllowNewOutgoingStreams(QuicStreamCount max_open_streams);

  // Checks if the incoming stream ID exceeds the MAX_STREAMS limit.  If the
  // limit is exceeded, populates |error_detials| and returns false.
  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId stream_id,
                                        std::string* error_details);

  // Returns true if |id| is still available.
  bool IsAvailableStream(QuicStreamId id) const;

  QuicStreamCount incoming_initial_max_open_streams() const {
    return incoming_initial_max_open_streams_;
  }

  QuicStreamId next_outgoing_stream_id() const {
    return next_outgoing_stream_id_;
  }

  // Number of streams that the peer believes that it can still create.
  QuicStreamCount available_incoming_streams() const;

  QuicStreamId largest_peer_created_stream_id() const {
    return largest_peer_created_stream_id_;
  }

  QuicStreamCount outgoing_max_streams() const { return outgoing_max_streams_; }
  QuicStreamCount incoming_actual_max_streams() const {
    return incoming_actual_max_streams_;
  }
  QuicStreamCount incoming_advertised_max_streams() const {
    return incoming_advertised_max_streams_;
  }
  QuicStreamCount outgoing_stream_count() const {
    return outgoing_stream_count_;
  }

 private:
  friend class test::QuicSessionPeer;
  friend class test::QuicStreamIdManagerPeer;

  // Check whether the MAX_STREAMS window has opened up enough and, if so,
  // generate and send a MAX_STREAMS frame.
  void MaybeSendMaxStreamsFrame();

  // Get what should be the first incoming/outgoing stream ID that
  // this stream id manager will manage, taking into account directionality and
  // client/server perspective.
  QuicStreamId GetFirstOutgoingStreamId() const;
  QuicStreamId GetFirstIncomingStreamId() const;

  // Back reference to the session containing this Stream ID Manager.
  DelegateInterface* delegate_;

  // Whether this stream id manager is for unidrectional (true) or bidirectional
  // (false) streams.
  const bool unidirectional_;

  // Is this manager a client or a server.
  const Perspective perspective_;

  // QUIC version used for this manager.
  const ParsedQuicVersion version_;

  // The number of streams that this node can initiate.
  // This limit is first set when config is negotiated, but may be updated upon
  // receiving MAX_STREAMS frame.
  QuicStreamCount outgoing_max_streams_;

  // The ID to use for the next outgoing stream.
  QuicStreamId next_outgoing_stream_id_;

  // The number of outgoing streams that have ever been opened, including those
  // that have been closed. This number must never be larger than
  // outgoing_max_streams_.
  QuicStreamCount outgoing_stream_count_;

  // FOR INCOMING STREAMS

  // The actual maximum number of streams that can be opened by the peer.
  QuicStreamCount incoming_actual_max_streams_;
  // Max incoming stream number that has been advertised to the peer and is <=
  // incoming_actual_max_streams_. It is set to incoming_actual_max_streams_
  // when a MAX_STREAMS is sent.
  QuicStreamCount incoming_advertised_max_streams_;

  // Initial maximum on the number of open streams allowed.
  QuicStreamCount incoming_initial_max_open_streams_;

  // The number of streams that have been created, including open ones and
  // closed ones.
  QuicStreamCount incoming_stream_count_;

  // Set of stream ids that are less than the largest stream id that has been
  // received, but are nonetheless available to be created.
  QuicHashSet<QuicStreamId> available_streams_;

  QuicStreamId largest_peer_created_stream_id_;
};
}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
