// 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)),
      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::Http2HeaderBlock 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::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
