// Copyright (c) 2015 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 "quiche/quic/test_tools/quic_spdy_session_peer.h"

#include <utility>

#include "absl/base/casts.h"
#include "quiche/quic/core/http/quic_spdy_session.h"
#include "quiche/quic/core/qpack/qpack_receive_stream.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/test_tools/quic_session_peer.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace quic {
namespace test {

// static
QuicHeadersStream* QuicSpdySessionPeer::GetHeadersStream(
    QuicSpdySession* session) {
  QUICHE_DCHECK(!VersionIsIetfQuic(session->transport_version()));
  return session->headers_stream();
}

void QuicSpdySessionPeer::SetHeadersStream(QuicSpdySession* session,
                                           QuicHeadersStream* headers_stream) {
  QUICHE_DCHECK(!VersionIsIetfQuic(session->transport_version()));
  for (auto& it : QuicSessionPeer::stream_map(session)) {
    if (it.first ==
        QuicUtils::GetHeadersStreamId(session->transport_version())) {
      it.second.reset(headers_stream);
      session->headers_stream_ =
          absl::down_cast<QuicHeadersStream*>(it.second.get());
      break;
    }
  }
}

// static
spdy::SpdyFramer* QuicSpdySessionPeer::GetSpdyFramer(QuicSpdySession* session) {
  return &session->spdy_framer_;
}

void QuicSpdySessionPeer::SetMaxInboundHeaderListSize(
    QuicSpdySession* session, size_t max_inbound_header_size) {
  session->set_max_inbound_header_list_size(max_inbound_header_size);
}

// static
size_t QuicSpdySessionPeer::WriteHeadersOnHeadersStream(
    QuicSpdySession* session, QuicStreamId id, quiche::HttpHeaderBlock headers,
    bool fin, const spdy::SpdyStreamPrecedence& precedence,
    quiche::QuicheReferenceCountedPointer<QuicAckListenerInterface>
        ack_listener) {
  return session->WriteHeadersOnHeadersStream(
      id, std::move(headers), fin, precedence, std::move(ack_listener));
}

// static
QuicStreamId QuicSpdySessionPeer::GetNextOutgoingUnidirectionalStreamId(
    QuicSpdySession* session) {
  return session->GetNextOutgoingUnidirectionalStreamId();
}

// static
QuicReceiveControlStream* QuicSpdySessionPeer::GetReceiveControlStream(
    QuicSpdySession* session) {
  return session->receive_control_stream_;
}

// static
QuicSendControlStream* QuicSpdySessionPeer::GetSendControlStream(
    QuicSpdySession* session) {
  return session->send_control_stream_;
}

// static
QpackSendStream* QuicSpdySessionPeer::GetQpackDecoderSendStream(
    QuicSpdySession* session) {
  return session->qpack_decoder_send_stream_;
}

// static
QpackSendStream* QuicSpdySessionPeer::GetQpackEncoderSendStream(
    QuicSpdySession* session) {
  return session->qpack_encoder_send_stream_;
}

// static
QpackReceiveStream* QuicSpdySessionPeer::GetQpackDecoderReceiveStream(
    QuicSpdySession* session) {
  return session->qpack_decoder_receive_stream_;
}

// static
QpackReceiveStream* QuicSpdySessionPeer::GetQpackEncoderReceiveStream(
    QuicSpdySession* session) {
  return session->qpack_encoder_receive_stream_;
}

// static
void QuicSpdySessionPeer::SetHttpDatagramSupport(
    QuicSpdySession* session, HttpDatagramSupport http_datagram_support) {
  session->http_datagram_support_ = http_datagram_support;
}

// static
HttpDatagramSupport QuicSpdySessionPeer::LocalHttpDatagramSupport(
    QuicSpdySession* session) {
  return session->LocalHttpDatagramSupport();
}

// static
void QuicSpdySessionPeer::EnableWebTransport(QuicSpdySession* session) {
  QUICHE_DCHECK(session->WillNegotiateWebTransport());
  SetHttpDatagramSupport(session, HttpDatagramSupport::kRfc);
  session->peer_web_transport_versions_ = kDefaultSupportedWebTransportVersions;
}

}  // namespace test
}  // namespace quic
