// 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_tools.h"

#include <memory>
#include <optional>
#include <ostream>
#include <string>
#include <utility>

#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "quiche/quic/core/crypto/proof_verifier.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/masque/masque_client.h"
#include "quiche/quic/masque/masque_client_session.h"
#include "quiche/quic/masque/masque_encapsulated_client.h"
#include "quiche/quic/masque/masque_utils.h"
#include "quiche/quic/platform/api/quic_default_proof_providers.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/tools/fake_proof_verifier.h"
#include "quiche/quic/tools/quic_name_lookup.h"
#include "quiche/quic/tools/quic_url.h"
#include "quiche/common/http/http_header_block.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_ip_address.h"

namespace quic {
namespace tools {

namespace {

// Helper class to ensure a fake address gets properly removed when this goes
// out of scope.
class FakeAddressRemover {
 public:
  FakeAddressRemover() = default;
  void IngestFakeAddress(const quiche::QuicheIpAddress& fake_address,
                         MasqueClientSession* masque_client_session) {
    QUICHE_CHECK(masque_client_session != nullptr);
    QUICHE_CHECK(!fake_address_.has_value());
    fake_address_ = fake_address;
    masque_client_session_ = masque_client_session;
  }
  ~FakeAddressRemover() {
    if (fake_address_.has_value()) {
      masque_client_session_->RemoveFakeAddress(*fake_address_);
    }
  }

 private:
  std::optional<quiche::QuicheIpAddress> fake_address_;
  MasqueClientSession* masque_client_session_ = nullptr;
};

}  // namespace

std::unique_ptr<MasqueEncapsulatedClient>
CreateAndConnectMasqueEncapsulatedClient(
    MasqueClient* masque_client, MasqueMode masque_mode,
    QuicEventLoop* event_loop, std::string url_string,
    bool disable_certificate_verification, int address_family_for_lookup,
    bool dns_on_client, bool is_also_underlying) {
  if (!masque_client->masque_client_session()->SupportsH3Datagram()) {
    QUIC_LOG(ERROR) << "Refusing to use MASQUE without datagram support";
    return nullptr;
  }

  QuicUrl url(url_string, "https");
  if (url.host().empty() && !absl::StrContains(url_string, "://")) {
    url = QuicUrl(absl::StrCat("https://", url_string));
  }
  if (url.host().empty()) {
    QUIC_LOG(ERROR) << "Failed to parse URL \"" << url_string << "\"";
    return nullptr;
  }

  std::unique_ptr<ProofVerifier> proof_verifier;
  if (disable_certificate_verification) {
    proof_verifier = std::make_unique<FakeProofVerifier>();
  } else {
    proof_verifier = CreateDefaultProofVerifier(url.host());
  }

  // Build the client, and try to connect.
  QuicSocketAddress addr;
  FakeAddressRemover fake_address_remover;
  if (dns_on_client) {
    addr = LookupAddress(address_family_for_lookup, url.host(),
                         absl::StrCat(url.port()));
    if (!addr.IsInitialized()) {
      QUIC_LOG(ERROR) << "Unable to resolve address: " << url.host();
      return nullptr;
    }
  } else {
    quiche::QuicheIpAddress fake_address =
        masque_client->masque_client_session()->GetFakeAddress(url.host());
    fake_address_remover.IngestFakeAddress(
        fake_address, masque_client->masque_client_session());
    addr = QuicSocketAddress(fake_address, url.port());
    QUICHE_CHECK(addr.IsInitialized());
  }
  const QuicServerId server_id(url.host(), url.port());
  std::unique_ptr<MasqueEncapsulatedClient> client;
  if (is_also_underlying) {
    client = MasqueEncapsulatedClient::Create(
        addr, server_id, url_string, masque_mode, event_loop,
        std::move(proof_verifier), masque_client);
  } else {
    client = std::make_unique<MasqueEncapsulatedClient>(
        addr, server_id, event_loop, std::move(proof_verifier), masque_client);
  }

  if (client == nullptr) {
    QUIC_LOG(ERROR) << "Failed to create MasqueEncapsulatedClient for "
                    << url_string;
    return nullptr;
  }

  if (!client->Prepare(
          MaxPacketSizeForEncapsulatedConnections(masque_client))) {
    QUIC_LOG(ERROR) << "Failed to prepare MasqueEncapsulatedClient for "
                    << url_string;
    return nullptr;
  }

  QUIC_LOG(INFO) << "Connected client "
                 << client->session()->connection()->client_connection_id()
                 << " server " << client->session()->connection_id() << " for "
                 << url_string;
  return client;
}

bool SendRequestOnMasqueEncapsulatedClient(MasqueEncapsulatedClient& client,
                                           std::string url_string) {
  const QuicUrl url(url_string, "https");
  // Construct the string body from flags, if provided.
  // TODO(dschinazi) Add support for HTTP POST and non-empty bodies.
  const std::string body = "";

  // Construct a GET request for supplied URL.
  quiche::HttpHeaderBlock header_block;
  header_block[":method"] = "GET";
  header_block[":scheme"] = url.scheme();
  header_block[":authority"] = url.HostPort();
  header_block[":path"] = url.PathParamsQuery();

  // Make sure to store the response, for later output.
  client.set_store_response(true);

  // Send the MASQUE init request.
  client.SendRequestAndWaitForResponse(header_block, body,
                                       /*fin=*/true);

  if (!client.connected()) {
    QUIC_LOG(ERROR) << "Request for " << url_string
                    << " caused connection failure. Error: "
                    << QuicErrorCodeToString(client.session()->error());
    return false;
  }

  const int response_code = client.latest_response_code();
  if (response_code < 200 || response_code >= 300) {
    QUIC_LOG(ERROR) << "Request for " << url_string
                    << " failed with HTTP response code " << response_code;
    return false;
  }

  const std::string response_body = client.latest_response_body();
  QUIC_LOG(INFO) << "Request succeeded for " << url_string << std::endl
                 << response_body;

  return true;
}

}  // namespace tools
}  // namespace quic
