// 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 "absl/base/nullability.h"
#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
#include "quiche/quic/core/http/quic_connection_migration_manager.h"
#include "quiche/quic/core/http/quic_spdy_client_session.h"
#include "quiche/quic/core/http/quic_spdy_client_stream.h"
#include "quiche/quic/core/http/quic_spdy_session.h"
#include "quiche/quic/core/quic_config.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_force_blockable_packet_writer.h"
#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_path_validator.h"
#include "quiche/quic/core/quic_server_id.h"
#include "quiche/quic/core/quic_session.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/tools/quic_client_base.h"
#include "quiche/quic/tools/quic_simple_client_stream.h"
#include "quiche/common/http/http_header_block.h"
#include "quiche/common/quiche_callbacks.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) {
        if (on_interim_headers_ != nullptr) {
          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
