// Copyright 2019 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/masque/masque_client.h"

#include <cstdint>
#include <memory>
#include <string>
#include <utility>

#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "quiche/quic/core/crypto/client_proof_source.h"
#include "quiche/quic/core/crypto/proof_verifier.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_connection.h"
#include "quiche/quic/core/quic_connection_id.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_session.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/masque/masque_client_session.h"
#include "quiche/quic/masque/masque_utils.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/tools/quic_client_default_network_helper.h"
#include "quiche/quic/tools/quic_default_client.h"
#include "quiche/quic/tools/quic_name_lookup.h"
#include "quiche/quic/tools/quic_url.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace quic {

MasqueClient::MasqueClient(QuicSocketAddress server_address,
                           const QuicServerId& server_id,
                           MasqueMode masque_mode, QuicEventLoop* event_loop,
                           std::unique_ptr<ProofVerifier> proof_verifier,
                           const std::string& uri_template)
    : QuicDefaultClient(server_address, server_id, MasqueSupportedVersions(),
                        event_loop, std::move(proof_verifier)),
      masque_mode_(masque_mode),
      uri_template_(uri_template) {
  QUICHE_CHECK(!QuicUrl(uri_template_).host().empty());
}

MasqueClient::MasqueClient(
    QuicSocketAddress server_address, const QuicServerId& server_id,
    MasqueMode masque_mode, QuicEventLoop* event_loop, const QuicConfig& config,
    std::unique_ptr<QuicClientDefaultNetworkHelper> network_helper,
    std::unique_ptr<ProofVerifier> proof_verifier,
    const std::string& uri_template)
    : QuicDefaultClient(server_address, server_id, MasqueSupportedVersions(),
                        config, event_loop, std::move(network_helper),
                        std::move(proof_verifier)),
      masque_mode_(masque_mode),
      uri_template_(uri_template) {
  QUICHE_CHECK(!QuicUrl(uri_template_).host().empty());
}

MasqueClient::MasqueClient(
    QuicSocketAddress server_address, const QuicServerId& server_id,
    QuicEventLoop* event_loop, const QuicConfig& config,
    std::unique_ptr<QuicClientDefaultNetworkHelper> network_helper,
    std::unique_ptr<ProofVerifier> proof_verifier)
    : QuicDefaultClient(server_address, server_id, MasqueSupportedVersions(),
                        config, event_loop, std::move(network_helper),
                        std::move(proof_verifier)) {}

std::unique_ptr<QuicSession> MasqueClient::CreateQuicClientSession(
    const ParsedQuicVersionVector& supported_versions,
    QuicConnection* connection) {
  QUIC_DLOG(INFO) << "Creating MASQUE session for "
                  << connection->connection_id();
  return std::make_unique<MasqueClientSession>(
      masque_mode_, uri_template_, *config(), supported_versions, connection,
      server_id(), crypto_config(), this);
}

MasqueClientSession* MasqueClient::masque_client_session() {
  return static_cast<MasqueClientSession*>(QuicDefaultClient::session());
}

QuicConnectionId MasqueClient::connection_id() {
  return masque_client_session()->connection_id();
}

std::string MasqueClient::authority() const {
  QuicUrl url(uri_template_);
  return absl::StrCat(url.host(), ":", url.port());
}

// static
std::unique_ptr<MasqueClient> MasqueClient::Create(
    const std::string& uri_template, MasqueMode masque_mode,
    QuicEventLoop* event_loop, std::unique_ptr<ProofVerifier> proof_verifier,
    std::unique_ptr<ClientProofSource> proof_source) {
  QuicUrl url(uri_template);
  std::string host = url.host();
  if (host.empty()) {
    QUIC_LOG(ERROR) << "Failed to parse URI template \"" << uri_template
                    << "\"";
    return nullptr;
  }
  uint16_t port = url.port();
  // Build the masque_client, and try to connect.
  QuicSocketAddress addr = tools::LookupAddress(host, absl::StrCat(port));
  if (!addr.IsInitialized()) {
    QUIC_LOG(ERROR) << "Unable to resolve address: " << host;
    return nullptr;
  }
  QuicServerId server_id(host, port);
  // Use absl::WrapUnique(new MasqueClient(...)) instead of
  // std::make_unique<MasqueClient>(...) because the constructor for
  // MasqueClient is private and therefore not accessible from make_unique.
  auto masque_client = absl::WrapUnique(
      new MasqueClient(addr, server_id, masque_mode, event_loop,
                       std::move(proof_verifier), uri_template));

  if (masque_client == nullptr) {
    QUIC_LOG(ERROR) << "Failed to create masque_client";
    return nullptr;
  }
  if (proof_source != nullptr) {
    masque_client->crypto_config()->set_proof_source(std::move(proof_source));
  }
  if (!masque_client->Prepare(kDefaultMaxPacketSizeForTunnels)) {
    QUIC_LOG(ERROR) << "Failed to prepare MASQUE client to " << host << ":"
                    << port;
    return nullptr;
  }
  return masque_client;
}

bool MasqueClient::Prepare(QuicByteCount max_packet_size) {
  set_initial_max_packet_length(max_packet_size);
  set_drop_response_body(false);
  if (!Initialize()) {
    QUIC_LOG(ERROR) << "Failed to initialize MASQUE client";
    return false;
  }
  if (!Connect()) {
    QuicErrorCode error = session()->error();
    QUIC_LOG(ERROR) << "Failed to connect. Error: "
                    << QuicErrorCodeToString(error);
    return false;
  }
  if (!WaitUntilSettingsReceived()) {
    QUIC_LOG(ERROR) << "Failed to receive settings";
    return false;
  }
  return true;
}

void MasqueClient::OnSettingsReceived() { settings_received_ = true; }

bool MasqueClient::WaitUntilSettingsReceived() {
  while (connected() && !settings_received_) {
    network_helper()->RunEventLoop();
  }
  return connected() && settings_received_;
}

}  // namespace quic
