// 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"

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, QuicStrCat(port));
  if (!addr.IsInitialized()) {
    QUIC_LOG(ERROR) << "Unable to resolve address: " << host;
    return nullptr;
  }
  QuicServerId server_id(host, port,
                         /*privacy_mode_enabled=*/false);
  auto masque_client = std::make_unique<MasqueEpollClient>(
      addr, server_id, epoll_server, std::move(proof_verifier),
      QuicStrCat(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 request.
  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::SendClientConnectionIdUnregister(
    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 init request.
  SendRequestAndWaitForResponse(header_block, body,
                                /*fin=*/true);
}

}  // namespace quic
