// 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 "quiche/quic/tools/quic_simple_client_session.h"

#include <memory>
#include <utility>

#include "quiche/quic/core/http/quic_spdy_client_session.h"
#include "quiche/quic/core/quic_path_validator.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/common/http/http_header_block.h"

namespace quic {

QuicSimpleClientSession::QuicSimpleClientSession(
    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
    QuicConnection* connection, QuicClientBase::NetworkHelper* network_helper,
    const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config,
    bool drop_response_body, bool enable_web_transport)
    : QuicSimpleClientSession(config, supported_versions, connection,
                              /*visitor=*/nullptr, network_helper, server_id,
                              crypto_config, drop_response_body,
                              enable_web_transport) {}

QuicSimpleClientSession::QuicSimpleClientSession(
    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
    QuicConnection* connection, QuicSession::Visitor* visitor,
    QuicClientBase::NetworkHelper* network_helper,
    const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config,
    bool drop_response_body, bool enable_web_transport)
    : QuicSimpleClientSession(config, supported_versions, connection, visitor,
                              /*writer=*/nullptr,
                              /*migration_helper=*/nullptr,
                              QuicConnectionMigrationConfig{
                                  .allow_server_preferred_address = false},
                              network_helper, server_id, crypto_config,
                              drop_response_body, enable_web_transport) {}

QuicSimpleClientSession::QuicSimpleClientSession(
    const QuicConfig& config, const ParsedQuicVersionVector& supported_versions,
    QuicConnection* connection, QuicSession::Visitor* visitor,
    QuicForceBlockablePacketWriter* absl_nullable writer,
    QuicMigrationHelper* absl_nullable migration_helper,
    const QuicConnectionMigrationConfig& migration_config,
    QuicClientBase::NetworkHelper* network_helper,
    const QuicServerId& server_id, QuicCryptoClientConfig* crypto_config,
    bool drop_response_body, bool enable_web_transport)
    : QuicSpdyClientSession(
          config, supported_versions, connection, visitor, writer,
          migration_helper, migration_config, server_id, crypto_config,
          enable_web_transport ? QuicPriorityType::kWebTransport
                               : QuicPriorityType::kHttp),
      network_helper_(network_helper),
      drop_response_body_(drop_response_body),
      enable_web_transport_(enable_web_transport) {}

std::unique_ptr<QuicSpdyClientStream>
QuicSimpleClientSession::CreateClientStream() {
  auto stream = std::make_unique<QuicSimpleClientStream>(
      GetNextOutgoingBidirectionalStreamId(), this, BIDIRECTIONAL,
      drop_response_body_);
  stream->set_on_interim_headers(
      [this](const quiche::HttpHeaderBlock& headers) {
        on_interim_headers_(headers);
      });
  return stream;
}

WebTransportHttp3VersionSet
QuicSimpleClientSession::LocallySupportedWebTransportVersions() const {
  return enable_web_transport_ ? kDefaultSupportedWebTransportVersions
                               : WebTransportHttp3VersionSet();
}

HttpDatagramSupport QuicSimpleClientSession::LocalHttpDatagramSupport() {
  return enable_web_transport_ ? HttpDatagramSupport::kRfcAndDraft04
                               : HttpDatagramSupport::kNone;
}

void QuicSimpleClientSession::CreateContextForMultiPortPath(
    std::unique_ptr<MultiPortPathContextObserver> context_observer) {
  if (!network_helper_ || connection()->multi_port_stats() == nullptr) {
    return;
  }
  auto self_address = connection()->self_address();
  auto server_address = connection()->peer_address();
  if (!network_helper_->CreateUDPSocketAndBind(
          server_address, self_address.host(), self_address.port() + 1)) {
    return;
  }
  QuicPacketWriter* writer = network_helper_->CreateQuicPacketWriter();
  if (writer == nullptr) {
    return;
  }
  context_observer->OnMultiPortPathContextAvailable(
      std::make_unique<PathMigrationContext>(
          std::unique_ptr<QuicPacketWriter>(writer),
          network_helper_->GetLatestClientAddress(), peer_address()));
}

void QuicSimpleClientSession::MigrateToMultiPortPath(
    std::unique_ptr<QuicPathValidationContext> context) {
  auto* path_migration_context =
      static_cast<PathMigrationContext*>(context.get());
  MigratePath(path_migration_context->self_address(),
              path_migration_context->peer_address(),
              path_migration_context->ReleaseWriter(), /*owns_writer=*/true);
}

}  // namespace quic
