// Copyright (c) 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 <iostream>
#include <memory>
#include <string>
#include <utility>

#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h"
#include "net/quic/platform/impl/quic_epoll_clock.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
#include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h"
#include "net/third_party/quiche/src/quic/tools/quic_client.h"
#include "net/third_party/quiche/src/quic/tools/quic_url.h"

DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
                              host,
                              "",
                              "The IP or hostname to connect to.");

DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");

namespace quic {

enum class Feature {
  // First row of features ("table stakes")
  // A version negotiation response is elicited and acted on.
  kVersionNegotiation,
  // The handshake completes successfully.
  kHandshake,
  // Stream data is being exchanged and ACK'ed.
  kStreamData,
  // The connection close procedcure completes with a zero error code.
  kConnectionClose,
  // A RETRY packet was successfully processed.
  kRetry,

  // Second row of features (anything else protocol-related)
  // We switched to a different port and the server migrated to it.
  kRebinding,

  // Third row of features (H3 tests)
  // An H3 transaction succeeded.
  kHttp3,
};

char MatrixLetter(Feature f) {
  switch (f) {
    case Feature::kVersionNegotiation:
      return 'V';
    case Feature::kHandshake:
      return 'H';
    case Feature::kStreamData:
      return 'D';
    case Feature::kConnectionClose:
      return 'C';
    case Feature::kHttp3:
      return '3';
    case Feature::kRetry:
      return 'S';
    case Feature::kRebinding:
      return 'B';
  }
}

std::set<Feature> AttemptRequest(QuicSocketAddress addr,
                                 std::string authority,
                                 QuicServerId server_id,
                                 bool test_version_negotiation,
                                 bool attempt_rebind) {
  ParsedQuicVersion version(PROTOCOL_TLS1_3, QUIC_VERSION_99);
  ParsedQuicVersionVector versions = {version};
  if (test_version_negotiation) {
    versions.insert(versions.begin(), QuicVersionReservedForNegotiation());
  }

  std::set<Feature> features;
  auto proof_verifier = std::make_unique<FakeProofVerifier>();
  QuicEpollServer epoll_server;
  QuicEpollClock epoll_clock(&epoll_server);
  auto client = std::make_unique<QuicClient>(
      addr, server_id, versions, &epoll_server, std::move(proof_verifier));
  if (!client->Initialize()) {
    QUIC_LOG(ERROR) << "Failed to initialize client";
    return features;
  }
  const bool connect_result = client->Connect();
  QuicConnection* connection = client->session()->connection();
  if (connection != nullptr) {
    QuicConnectionStats client_stats = connection->GetStats();
    if (client_stats.retry_packet_processed) {
      features.insert(Feature::kRetry);
    }
    if (test_version_negotiation && connection->version() == version) {
      features.insert(Feature::kVersionNegotiation);
    }
  }
  if (test_version_negotiation && !connect_result) {
    // Failed to negotiate version, retry without version negotiation.
    std::set<Feature> features_without_version_negotiation =
        AttemptRequest(addr, authority, server_id,
                       /*test_version_negotiation=*/false, attempt_rebind);

    features.insert(features_without_version_negotiation.begin(),
                    features_without_version_negotiation.end());
    return features;
  }
  if (!client->session()->IsCryptoHandshakeConfirmed()) {
    return features;
  }
  features.insert(Feature::kHandshake);

  // Construct and send a request.
  spdy::SpdyHeaderBlock header_block;
  header_block[":method"] = "GET";
  header_block[":scheme"] = "https";
  header_block[":authority"] = authority;
  header_block[":path"] = "/";
  client->set_store_response(true);
  client->SendRequest(header_block, "", /*fin=*/true);

  const QuicTime request_start_time = epoll_clock.Now();
  static const auto request_timeout = QuicTime::Delta::FromSeconds(20);
  bool request_timed_out = false;
  while (client->WaitForEvents()) {
    if (epoll_clock.Now() - request_start_time >= request_timeout) {
      QUIC_LOG(ERROR) << "Timed out waiting for HTTP response";
      request_timed_out = true;
      break;
    }
  }

  if (connection != nullptr) {
    QuicConnectionStats client_stats = connection->GetStats();
    QuicSentPacketManager* sent_packet_manager =
        test::QuicConnectionPeer::GetSentPacketManager(connection);
    const bool received_forward_secure_ack =
        sent_packet_manager != nullptr &&
        sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)
            .IsInitialized();
    if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) {
      features.insert(Feature::kStreamData);
    }
  }

  if (request_timed_out || !client->connected()) {
    return features;
  }

  if (client->latest_response_code() != -1) {
    features.insert(Feature::kHttp3);

    if (attempt_rebind) {
      // Now make a second request after switching to a different client port.
      if (client->ChangeEphemeralPort()) {
        client->SendRequest(header_block, "", /*fin=*/true);

        const QuicTime second_request_start_time = epoll_clock.Now();
        while (client->WaitForEvents()) {
          if (epoll_clock.Now() - second_request_start_time >=
              request_timeout) {
            // Rebinding does not work, retry without attempting it.
            std::set<Feature> features_without_rebind = AttemptRequest(
                addr, authority, server_id, test_version_negotiation,
                /*attempt_rebind=*/false);
            features.insert(features_without_rebind.begin(),
                            features_without_rebind.end());
            return features;
          }
        }
        features.insert(Feature::kRebinding);
      } else {
        QUIC_LOG(ERROR) << "Failed to change ephemeral port";
      }
    }
  }

  if (connection != nullptr && connection->connected()) {
    test::QuicConnectionPeer::SendConnectionClosePacket(
        connection, QUIC_NO_ERROR, "Graceful close");
    const QuicTime close_start_time = epoll_clock.Now();
    static const auto close_timeout = QuicTime::Delta::FromSeconds(10);
    while (client->connected()) {
      client->epoll_network_helper()->RunEventLoop();
      if (epoll_clock.Now() - close_start_time >= close_timeout) {
        QUIC_LOG(ERROR) << "Timed out waiting for connection close";
        return features;
      }
    }
    const QuicErrorCode received_error = client->session()->error();
    if (received_error == QUIC_NO_ERROR ||
        received_error == QUIC_PUBLIC_RESET) {
      features.insert(Feature::kConnectionClose);
    } else {
      QUIC_LOG(ERROR) << "Received error " << client->session()->error() << " "
                      << client->session()->error_details();
    }
  }

  return features;
}

std::set<Feature> ServerSupport(std::string host, int port) {
  // Enable IETF version support.
  QuicVersionInitializeSupportForIetfDraft();
  QuicEnableVersion(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99));

  // Build the client, and try to connect.
  QuicSocketAddress addr = tools::LookupAddress(host, QuicStrCat(port));
  if (!addr.IsInitialized()) {
    QUIC_LOG(ERROR) << "Failed to resolve " << host;
    return std::set<Feature>();
  }
  QuicServerId server_id(host, port, false);
  std::string authority = QuicStrCat(host, ":", port);

  return AttemptRequest(addr, authority, server_id,
                        /*test_version_negotiation=*/true,
                        /*attempt_rebind=*/true);
}

}  // namespace quic

int main(int argc, char* argv[]) {
  QuicSystemEventLoop event_loop("quic_client");
  const char* usage = "Usage: quic_client_interop_test [options] [url]";

  std::vector<std::string> args =
      quic::QuicParseCommandLineFlags(usage, argc, argv);
  if (args.size() > 1) {
    quic::QuicPrintCommandLineFlagHelp(usage);
    exit(1);
  }
  std::string host = GetQuicFlag(FLAGS_host);
  int port = GetQuicFlag(FLAGS_port);

  if (!args.empty()) {
    quic::QuicUrl url(args[0], "https");
    if (host.empty()) {
      host = url.host();
    }
    if (port == 0) {
      port = url.port();
    }
  }
  if (port == 0) {
    port = 443;
  }
  if (host.empty()) {
    quic::QuicPrintCommandLineFlagHelp(usage);
    exit(1);
  }

  auto supported_features = quic::ServerSupport(host, port);
  std::cout << "Results for " << host << ":" << port << std::endl;
  int current_row = 1;
  for (auto feature : supported_features) {
    if (current_row < 2 && feature >= quic::Feature::kRebinding) {
      std::cout << std::endl;
      current_row = 2;
    }
    if (current_row < 3 && feature >= quic::Feature::kHttp3) {
      std::cout << std::endl;
      current_row = 3;
    }
    std::cout << MatrixLetter(feature);
  }
  std::cout << std::endl;
}
