// 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 NET_THIRD_PARTY_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
#define NET_THIRD_PARTY_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_

#include "net/third_party/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  // NET_THIRD_PARTY_QUIC_CORE_LEGACY_QUIC_STREAM_ID_MANAGER_H_
