// 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 "quic/masque/masque_epoll_client.h"

#include <string>

#include "absl/memory/memory.h"
#include "quic/masque/masque_client_session.h"
#include "quic/masque/masque_utils.h"
#include "quic/tools/quic_url.h"

namespace quic {

MasqueEpollClient::MasqueEpollClient(
    QuicSocketAddress server_address, const QuicServerId& server_id,
    MasqueMode masque_mode, QuicEpollServer* epoll_server,
    std::unique_ptr<ProofVerifier> proof_verifier,
    const std::string& uri_template)
    : QuicClient(server_address, server_id, MasqueSupportedVersions(),
                 epoll_server, std::move(proof_verifier)),
      masque_mode_(masque_mode),
      uri_template_(uri_template) {}

std::unique_ptr<QuicSession> MasqueEpollClient::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(), push_promise_index(), this);
}

MasqueClientSession* MasqueEpollClient::masque_client_session() {
  return static_cast<MasqueClientSession*>(QuicClient::session());
}

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

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

// static
std::unique_ptr<MasqueEpollClient> MasqueEpollClient::Create(
    const std::string& uri_template, MasqueMode masque_mode,
    QuicEpollServer* epoll_server,
    std::unique_ptr<ProofVerifier> proof_verifier) {
  QuicUrl url(uri_template);
  std::string host = url.host();
  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 MasqueEpollClient(...)) instead of
  // std::make_unique<MasqueEpollClient>(...) because the constructor for
  // MasqueEpollClient is private and therefore not accessible from make_unique.
  auto masque_client = absl::WrapUnique(
      new MasqueEpollClient(addr, server_id, masque_mode, epoll_server,
                            std::move(proof_verifier), uri_template));

  if (masque_client == nullptr) {
    QUIC_LOG(ERROR) << "Failed to create masque_client";
    return nullptr;
  }

  masque_client->set_initial_max_packet_length(kMasqueMaxOuterPacketSize);
  masque_client->set_drop_response_body(false);
  if (!masque_client->Initialize()) {
    QUIC_LOG(ERROR) << "Failed to initialize masque_client";
    return nullptr;
  }
  if (!masque_client->Connect()) {
    QuicErrorCode error = masque_client->session()->error();
    QUIC_LOG(ERROR) << "Failed to connect to " << host << ":" << port
                    << ". Error: " << QuicErrorCodeToString(error);
    return nullptr;
  }

  if (!masque_client->WaitUntilSettingsReceived()) {
    QUIC_LOG(ERROR) << "Failed to receive settings";
    return nullptr;
  }

  if (masque_client->masque_mode() == MasqueMode::kLegacy) {
    // Construct the legacy mode init request.
    spdy::Http2HeaderBlock header_block;
    header_block[":method"] = "POST";
    header_block[":scheme"] = "https";
    header_block[":authority"] = masque_client->authority();
    header_block[":path"] = "/.well-known/masque/init";
    std::string body = "foo";

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

    // Send the MASQUE init command.
    masque_client->SendRequestAndWaitForResponse(header_block, body,
                                                 /*fin=*/true);

    if (!masque_client->connected()) {
      QUIC_LOG(ERROR)
          << "MASQUE init request caused connection failure. Error: "
          << QuicErrorCodeToString(masque_client->session()->error());
      return nullptr;
    }

    const int response_code = masque_client->latest_response_code();
    if (response_code != 200) {
      QUIC_LOG(ERROR) << "MASQUE init request failed with HTTP response code "
                      << response_code;
      return nullptr;
    }
  }
  return masque_client;
}

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

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

void MasqueEpollClient::UnregisterClientConnectionId(
    QuicConnectionId client_connection_id) {
  std::string body(client_connection_id.data(), client_connection_id.length());

  // Construct a GET or POST request for supplied URL.
  spdy::Http2HeaderBlock header_block;
  header_block[":method"] = "POST";
  header_block[":scheme"] = "https";
  header_block[":authority"] = authority();
  header_block[":path"] = "/.well-known/masque/unregister";

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

  // Send the MASQUE unregister command.
  SendRequest(header_block, body, /*fin=*/true);
}

}  // namespace quic
