// 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 "net/third_party/quiche/src/quic/masque/masque_epoll_client.h"
#include "net/third_party/quiche/src/quic/masque/masque_client_session.h"
#include "net/third_party/quiche/src/quic/masque/masque_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"

namespace quic {

MasqueEpollClient::MasqueEpollClient(
    QuicSocketAddress server_address,
    const QuicServerId& server_id,
    QuicEpollServer* epoll_server,
    std::unique_ptr<ProofVerifier> proof_verifier,
    const std::string& authority)
    : QuicClient(server_address,
                 server_id,
                 MasqueSupportedVersions(),
                 epoll_server,
                 std::move(proof_verifier)),
      epoll_server_(epoll_server),
      authority_(authority) {}

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>(
      *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();
}

// static
std::unique_ptr<MasqueEpollClient> MasqueEpollClient::Create(
    const std::string& host,
    int port,
    QuicEpollServer* epoll_server,
    std::unique_ptr<ProofVerifier> proof_verifier) {
  // Build the masque_client, and try to connect.
  QuicSocketAddress addr =
      tools::LookupAddress(host, quiche::QuicheStrCat(port));
  if (!addr.IsInitialized()) {
    QUIC_LOG(ERROR) << "Unable to resolve address: " << host;
    return nullptr;
  }
  QuicServerId server_id(host, port);
  // Use QuicWrapUnique(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 = QuicWrapUnique(new MasqueEpollClient(
      addr, server_id, epoll_server, std::move(proof_verifier),
      quiche::QuicheStrCat(host, ":", port)));

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

  masque_client->set_initial_max_packet_length(kDefaultMaxPacketSize);
  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;
  }

  std::string body = "foo";

  // Construct a GET or POST request for supplied URL.
  spdy::SpdyHeaderBlock header_block;
  header_block[":method"] = "POST";
  header_block[":scheme"] = "https";
  header_block[":authority"] = masque_client->authority_;
  header_block[":path"] = "/.well-known/masque/init";

  // 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::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::SpdyHeaderBlock 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
