// 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 "absl/container/flat_hash_set.h"
#include "absl/strings/str_cat.h"
#include "quic/core/frames/quic_frame.h"
#include "quic/core/quic_types.h"
#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_logging.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 absl::StrCat(
        " { 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.
  absl::flat_hash_set<QuicStreamId> available_streams_;

  QuicStreamId largest_peer_created_stream_id_;
};
}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_ID_MANAGER_H_
