// 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.

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

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

namespace quic {

UberQuicStreamIdManager::UberQuicStreamIdManager(
    QuicSession* session,
    QuicStreamCount max_open_outgoing_bidirectional_streams,
    QuicStreamCount max_open_outgoing_unidirectional_streams,
    QuicStreamCount max_open_incoming_bidirectional_streams,
    QuicStreamCount max_open_incoming_unidirectional_streams)
    : bidirectional_stream_id_manager_(session,
                                       /*unidirectional=*/false,
                                       max_open_outgoing_bidirectional_streams,
                                       max_open_incoming_bidirectional_streams),
      unidirectional_stream_id_manager_(
          session,
          /*unidirectional=*/true,
          max_open_outgoing_unidirectional_streams,
          max_open_incoming_unidirectional_streams) {}
void UberQuicStreamIdManager::RegisterStaticStream(
    QuicStreamId id,
    bool stream_already_counted) {
  if (QuicUtils::IsBidirectionalStreamId(id)) {
    bidirectional_stream_id_manager_.RegisterStaticStream(
        id, stream_already_counted);
    return;
  }
  unidirectional_stream_id_manager_.RegisterStaticStream(
      id, stream_already_counted);
}

void UberQuicStreamIdManager::AdjustMaxOpenOutgoingUnidirectionalStreams(
    size_t max_streams) {
  unidirectional_stream_id_manager_.AdjustMaxOpenOutgoingStreams(max_streams);
}
void UberQuicStreamIdManager::AdjustMaxOpenOutgoingBidirectionalStreams(
    size_t max_streams) {
  bidirectional_stream_id_manager_.AdjustMaxOpenOutgoingStreams(max_streams);
}

// TODO(fkastenholz): SetMax is cognizant of the number of static streams and
// sets the maximum to be max_streams + number_of_statics. This should
// eventually be removed from IETF QUIC.
void UberQuicStreamIdManager::SetMaxOpenOutgoingBidirectionalStreams(
    size_t max_open_streams) {
  bidirectional_stream_id_manager_.SetMaxOpenOutgoingStreams(max_open_streams);
}
void UberQuicStreamIdManager::SetMaxOpenOutgoingUnidirectionalStreams(
    size_t max_open_streams) {
  unidirectional_stream_id_manager_.SetMaxOpenOutgoingStreams(max_open_streams);
}
void UberQuicStreamIdManager::SetMaxOpenIncomingBidirectionalStreams(
    size_t max_open_streams) {
  bidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
}
void UberQuicStreamIdManager::SetMaxOpenIncomingUnidirectionalStreams(
    size_t max_open_streams) {
  unidirectional_stream_id_manager_.SetMaxOpenIncomingStreams(max_open_streams);
}

bool UberQuicStreamIdManager::CanOpenNextOutgoingBidirectionalStream() {
  return bidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
}

bool UberQuicStreamIdManager::CanOpenNextOutgoingUnidirectionalStream() {
  return unidirectional_stream_id_manager_.CanOpenNextOutgoingStream();
}

QuicStreamId UberQuicStreamIdManager::GetNextOutgoingBidirectionalStreamId() {
  return bidirectional_stream_id_manager_.GetNextOutgoingStreamId();
}

QuicStreamId UberQuicStreamIdManager::GetNextOutgoingUnidirectionalStreamId() {
  return unidirectional_stream_id_manager_.GetNextOutgoingStreamId();
}

bool UberQuicStreamIdManager::MaybeIncreaseLargestPeerStreamId(
    QuicStreamId id) {
  if (QuicUtils::IsBidirectionalStreamId(id)) {
    return bidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
        id);
  }
  return unidirectional_stream_id_manager_.MaybeIncreaseLargestPeerStreamId(id);
}

void UberQuicStreamIdManager::OnStreamClosed(QuicStreamId id) {
  if (QuicUtils::IsBidirectionalStreamId(id)) {
    bidirectional_stream_id_manager_.OnStreamClosed(id);
    return;
  }
  unidirectional_stream_id_manager_.OnStreamClosed(id);
}

bool UberQuicStreamIdManager::OnMaxStreamsFrame(
    const QuicMaxStreamsFrame& frame) {
  if (frame.unidirectional) {
    return unidirectional_stream_id_manager_.OnMaxStreamsFrame(frame);
  }
  return bidirectional_stream_id_manager_.OnMaxStreamsFrame(frame);
}

bool UberQuicStreamIdManager::OnStreamsBlockedFrame(
    const QuicStreamsBlockedFrame& frame) {
  if (frame.unidirectional) {
    return unidirectional_stream_id_manager_.OnStreamsBlockedFrame(frame);
  }
  return bidirectional_stream_id_manager_.OnStreamsBlockedFrame(frame);
}

bool UberQuicStreamIdManager::IsIncomingStream(QuicStreamId id) const {
  if (QuicUtils::IsBidirectionalStreamId(id)) {
    return bidirectional_stream_id_manager_.IsIncomingStream(id);
  }
  return unidirectional_stream_id_manager_.IsIncomingStream(id);
}

bool UberQuicStreamIdManager::IsAvailableStream(QuicStreamId id) const {
  if (QuicUtils::IsBidirectionalStreamId(id)) {
    return bidirectional_stream_id_manager_.IsAvailableStream(id);
  }
  return unidirectional_stream_id_manager_.IsAvailableStream(id);
}

size_t UberQuicStreamIdManager::GetMaxAllowdIncomingBidirectionalStreams()
    const {
  return bidirectional_stream_id_manager_.incoming_initial_max_open_streams();
}

size_t UberQuicStreamIdManager::GetMaxAllowdIncomingUnidirectionalStreams()
    const {
  return unidirectional_stream_id_manager_.incoming_initial_max_open_streams();
}

void UberQuicStreamIdManager::SetLargestPeerCreatedStreamId(
    QuicStreamId largest_peer_created_stream_id) {
  if (QuicUtils::IsBidirectionalStreamId(largest_peer_created_stream_id)) {
    bidirectional_stream_id_manager_.set_largest_peer_created_stream_id(
        largest_peer_created_stream_id);
    return;
  }
  unidirectional_stream_id_manager_.set_largest_peer_created_stream_id(
      largest_peer_created_stream_id);
}

QuicStreamId UberQuicStreamIdManager::next_outgoing_bidirectional_stream_id()
    const {
  return bidirectional_stream_id_manager_.next_outgoing_stream_id();
}

QuicStreamId UberQuicStreamIdManager::next_outgoing_unidirectional_stream_id()
    const {
  return unidirectional_stream_id_manager_.next_outgoing_stream_id();
}

size_t UberQuicStreamIdManager::max_allowed_outgoing_bidirectional_streams()
    const {
  return bidirectional_stream_id_manager_.outgoing_max_streams();
}

size_t UberQuicStreamIdManager::max_allowed_outgoing_unidirectional_streams()
    const {
  return unidirectional_stream_id_manager_.outgoing_max_streams();
}

QuicStreamCount
UberQuicStreamIdManager::actual_max_allowed_incoming_bidirectional_streams()
    const {
  return bidirectional_stream_id_manager_.incoming_actual_max_streams();
}

QuicStreamCount
UberQuicStreamIdManager::actual_max_allowed_incoming_unidirectional_streams()
    const {
  return unidirectional_stream_id_manager_.incoming_actual_max_streams();
}

QuicStreamCount
UberQuicStreamIdManager::advertised_max_allowed_incoming_bidirectional_streams()
    const {
  return bidirectional_stream_id_manager_.incoming_advertised_max_streams();
}

QuicStreamCount UberQuicStreamIdManager::
    advertised_max_allowed_incoming_unidirectional_streams() const {
  return unidirectional_stream_id_manager_.incoming_advertised_max_streams();
}

}  // namespace quic
