// 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_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/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 {
  // 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,
  // An H3 transaction succeeded.
  kHttp3,
  // A RETRY packet was successfully processed.
  kRetry,
};

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';
  }
}

std::set<Feature> AttemptRequest(QuicSocketAddress addr,
                                 std::string authority,
                                 QuicServerId server_id,
                                 ParsedQuicVersionVector versions) {
  std::set<Feature> features;
  auto proof_verifier = std::make_unique<FakeProofVerifier>();
  QuicEpollServer epoll_server;
  auto client = std::make_unique<QuicClient>(
      addr, server_id, versions, &epoll_server, std::move(proof_verifier));
  if (!client->Initialize()) {
    return features;
  }
  if (!client->Connect()) {
    QuicErrorCode error = client->session()->error();
    if (error == QUIC_INVALID_VERSION) {
      // QuicFramer::ProcessPacket returns RaiseError(QUIC_INVALID_VERSION) if
      // it receives a packet containing a version in the header that is not our
      // version. It might be possible that we didn't actually process a VN
      // packet here.
      features.insert(Feature::kVersionNegotiation);
      return features;
    }
    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);

  // TODO(nharper): After some period of time, time out and don't report
  // success.
  while (client->WaitForEvents()) {
  }

  QuicConnectionStats client_stats =
      client->session()->connection()->GetStats();
  if (client_stats.retry_packet_processed) {
    features.insert(Feature::kRetry);
  }

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

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

  // TODO(nharper): Properly check that we actually sent stream data and
  // received ACKs for it.
  features.insert(Feature::kStreamData);
  // TODO(nharper): Check that we sent/received (which one?) a CONNECTION_CLOSE
  // with error code 0.
  features.insert(Feature::kConnectionClose);
  return features;
}

std::set<Feature> ServerSupport(std::string host, int port) {
  // Configure version list.
  QuicVersionInitializeSupportForIetfDraft();
  ParsedQuicVersion version =
      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99);
  ParsedQuicVersionVector versions = {version};
  QuicEnableVersion(version);

  // Build the client, and try to connect.
  QuicSocketAddress addr = tools::LookupAddress(host, QuicStrCat(port));
  QuicServerId server_id(host, port, false);
  std::string authority = QuicStrCat(host, ":", port);

  ParsedQuicVersionVector versions_with_negotiation = versions;
  versions_with_negotiation.insert(versions_with_negotiation.begin(),
                                   QuicVersionReservedForNegotiation());
  auto supported_features =
      AttemptRequest(addr, authority, server_id, versions_with_negotiation);
  if (!supported_features.empty()) {
    supported_features.insert(Feature::kVersionNegotiation);
  } else {
    supported_features = AttemptRequest(addr, authority, server_id, versions);
  }
  return supported_features;
}

}  // 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 << "Supported features: ";
  for (auto feature : supported_features) {
    std::cout << MatrixLetter(feature);
  }
  std::cout << std::endl;
}
