#ifndef QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
#define QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_

#include "net/third_party/quiche/src/quic/core/quic_stream_id_manager.h"

namespace quic {

namespace test {
class QuicSessionPeer;
}  // namespace test

class QuicSession;

// Manages Google QUIC stream IDs. This manager is responsible for two
// questions: 1) can next outgoing stream ID be allocated (if yes, what is the
// next outgoing stream ID) and 2) can a new incoming stream be opened.
class QUIC_EXPORT_PRIVATE LegacyQuicStreamIdManager {
 public:
  LegacyQuicStreamIdManager(QuicSession* session,
                            size_t max_open_outgoing_streams,
                            size_t max_open_incoming_streams);

  ~LegacyQuicStreamIdManager();

  // Returns true if the next outgoing stream ID can be allocated.
  bool CanOpenNextOutgoingStream(
      size_t current_num_open_outgoing_streams) const;

  // Returns true if a new incoming stream can be opened.
  bool CanOpenIncomingStream(size_t current_num_open_incoming_streams) const;

  bool MaybeIncreaseLargestPeerStreamId(const QuicStreamId id);

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

  // Returns the stream ID for a new outgoing stream, and increments the
  // underlying counter.
  QuicStreamId GetNextOutgoingStreamId();

  // Return true if |id| is peer initiated.
  bool IsIncomingStream(QuicStreamId id) const;

  size_t MaxAvailableStreams() const;

  void set_max_open_incoming_streams(size_t max_open_incoming_streams) {
    max_open_incoming_streams_ = max_open_incoming_streams;
  }

  void set_max_open_outgoing_streams(size_t max_open_outgoing_streams) {
    max_open_outgoing_streams_ = max_open_outgoing_streams;
  }

  void set_largest_peer_created_stream_id(
      QuicStreamId largest_peer_created_stream_id) {
    largest_peer_created_stream_id_ = largest_peer_created_stream_id;
  }

  size_t max_open_incoming_streams() const {
    return max_open_incoming_streams_;
  }

  size_t max_open_outgoing_streams() const {
    return max_open_outgoing_streams_;
  }

  QuicStreamId next_outgoing_stream_id() const {
    return next_outgoing_stream_id_;
  }

  QuicStreamId largest_peer_created_stream_id() const {
    return largest_peer_created_stream_id_;
  }

 private:
  friend class test::QuicSessionPeer;

  size_t GetNumAvailableStreams() const;

  // Not owned.
  QuicSession* session_;

  // The maximum number of outgoing streams this connection can open.
  size_t max_open_outgoing_streams_;

  // The maximum number of incoming streams this connection will allow.
  size_t max_open_incoming_streams_;

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

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

  QuicStreamId largest_peer_created_stream_id_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
