// Copyright (c) 2012 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.

// Definitions and utility functions related to handling of QUIC versions.
//
// QUIC versions are encoded over the wire as an opaque 32bit field. The wire
// encoding is represented in memory as a QuicVersionLabel type (which is an
// alias to uint32_t). Conceptual versions are represented in memory as
// ParsedQuicVersion.
//
// We currently support two kinds of QUIC versions, GoogleQUIC and IETF QUIC.
//
// All GoogleQUIC versions use a wire encoding that matches the following regex
// when converted to ASCII: "[QT]0\d\d" (e.g. Q050). Q or T distinguishes the
// type of handshake used (Q for the QUIC_CRYPTO handshake, T for the QUIC+TLS
// handshake), and the two digits at the end contain the numeric value of
// the transport version used.
//
// All IETF QUIC versions use the wire encoding described in:
// https://tools.ietf.org/html/draft-ietf-quic-transport

#ifndef QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
#define QUICHE_QUIC_CORE_QUIC_VERSIONS_H_

#include <cstdint>
#include <string>
#include <vector>

#include "absl/base/macros.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/quic_tag.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/platform/api/quic_export.h"

namespace quic {

// The list of existing QUIC transport versions. Note that QUIC versions are
// sent over the wire as an encoding of ParsedQuicVersion, which requires a
// QUIC transport version and handshake protocol. For transport versions of the
// form QUIC_VERSION_XX where XX is decimal, the enum numeric value is
// guaranteed to match the name. Older deprecated transport versions are
// documented in comments below.
enum QuicTransportVersion {
  // Special case to indicate unknown/unsupported QUIC version.
  QUIC_VERSION_UNSUPPORTED = 0,

  // Version 1 was the first version of QUIC that supported versioning.
  // Version 2 decoupled versioning of non-cryptographic parameters from the
  //           SCFG.
  // Version 3 moved public flags into the beginning of the packet.
  // Version 4 added support for variable-length connection IDs.
  // Version 5 made specifying FEC groups optional.
  // Version 6 introduced variable-length packet numbers.
  // Version 7 introduced a lower-overhead encoding for stream frames.
  // Version 8 made salt length equal to digest length for the RSA-PSS
  //           signatures.
  // Version 9 added stream priority.
  // Version 10 redid the frame type numbering.
  // Version 11 reduced the length of null encryption authentication tag
  //            from 16 to 12 bytes.
  // Version 12 made the sequence numbers in the ACK frames variable-sized.
  // Version 13 added the dedicated header stream.
  // Version 14 added byte_offset to RST_STREAM frame.
  // Version 15 added a list of packets recovered using FEC to the ACK frame.
  // Version 16 added STOP_WAITING frame.
  // Version 17 added per-stream flow control.
  // Version 18 added PING frame.
  // Version 19 added connection-level flow control
  // Version 20 allowed to set stream- and connection-level flow control windows
  //            to different values.
  // Version 21 made header and crypto streams flow-controlled.
  // Version 22 added support for SCUP (server config update) messages.
  // Version 23 added timestamps into the ACK frame.
  // Version 24 added SPDY/4 header compression.
  // Version 25 added support for SPDY/4 header keys and removed error_details
  //            from RST_STREAM frame.
  // Version 26 added XLCT (expected leaf certificate) tag into CHLO.
  // Version 27 added a nonce into SHLO.
  // Version 28 allowed receiver to refuse creating a requested stream.
  // Version 29 added support for QUIC_STREAM_NO_ERROR.
  // Version 30 added server-side support for certificate transparency.
  // Version 31 incorporated the hash of CHLO into the crypto proof supplied by
  //            the server.
  // Version 32 removed FEC-related fields from wire format.
  // Version 33 added diversification nonces.
  // Version 34 removed entropy bits from packets and ACK frames, removed
  //            private flag from packet header and changed the ACK format to
  //            specify ranges of packets acknowledged rather than missing
  //            ranges.
  // Version 35 allows endpoints to independently set stream limit.
  // Version 36 added support for forced head-of-line blocking experiments.
  // Version 37 added perspective into null encryption.
  // Version 38 switched to IETF padding frame format and support for NSTP (no
  //            stop waiting frame) connection option.

  // Version 39 writes integers and floating numbers in big endian, stops acking
  // acks, sends a connection level WINDOW_UPDATE every 20 sent packets which do
  // not contain retransmittable frames.

  // Version 40 was an attempt to convert QUIC to IETF frame format; it was
  //            never shipped due to a bug.
  // Version 41 was a bugfix for version 40.  The working group changed the wire
  //            format before it shipped, which caused it to be never shipped
  //            and all the changes from it to be reverted.  No changes from v40
  //            or v41 are present in subsequent versions.
  // Version 42 allowed receiving overlapping stream data.

  QUIC_VERSION_43 = 43,  // PRIORITY frames are sent by client and accepted by
                         // server.
  // Version 44 used IETF header format from draft-ietf-quic-invariants-05.

  // Version 45 added MESSAGE frame.

  QUIC_VERSION_46 = 46,  // Use IETF draft-17 header format with demultiplexing
                         // bit.
  // Version 47 added variable-length QUIC server connection IDs.
  // Version 48 added CRYPTO frames for the handshake.
  // Version 49 added client connection IDs, long header lengths, and the IETF
  // header format from draft-ietf-quic-invariants-06
  QUIC_VERSION_50 = 50,  // Header protection and initial obfuscators.
  // Number 51 was T051 which used draft-29 features but with GoogleQUIC frames.
  // Number 70 used to represent draft-ietf-quic-transport-25.
  // Number 71 used to represent draft-ietf-quic-transport-27.
  // Number 72 used to represent draft-ietf-quic-transport-28.
  QUIC_VERSION_IETF_DRAFT_29 = 73,    // draft-ietf-quic-transport-29.
  QUIC_VERSION_IETF_RFC_V1 = 80,      // RFC 9000.
  QUIC_VERSION_IETF_2_DRAFT_01 = 81,  // draft-ietf-quic-v2-01.
  // Version 99 was a dumping ground for IETF QUIC changes which were not yet
  // ready for production between 2018-02 and 2020-02.

  // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a
  // which is part of a range reserved by the IETF for version negotiation
  // testing (see the "Versions" section of draft-ietf-quic-transport).
  // This version is intentionally meant to never be supported to trigger
  // version negotiation when proposed by clients and to prevent client
  // ossification when sent by servers.
  QUIC_VERSION_RESERVED_FOR_NEGOTIATION = 999,
};

// Helper function which translates from a QuicTransportVersion to a string.
// Returns strings corresponding to enum names (e.g. QUIC_VERSION_6).
QUIC_EXPORT_PRIVATE std::string QuicVersionToString(
    QuicTransportVersion transport_version);

// The crypto handshake protocols that can be used with QUIC.
// We are planning on eventually deprecating PROTOCOL_QUIC_CRYPTO in favor of
// PROTOCOL_TLS1_3.
enum HandshakeProtocol {
  PROTOCOL_UNSUPPORTED,
  PROTOCOL_QUIC_CRYPTO,
  PROTOCOL_TLS1_3,
};

// Helper function which translates from a HandshakeProtocol to a string.
QUIC_EXPORT_PRIVATE std::string HandshakeProtocolToString(
    HandshakeProtocol handshake_protocol);

// Returns whether |transport_version| uses CRYPTO frames for the handshake
// instead of stream 1.
QUIC_EXPORT_PRIVATE constexpr bool QuicVersionUsesCryptoFrames(
    QuicTransportVersion transport_version) {
  // CRYPTO frames were added in version 48.
  return transport_version > QUIC_VERSION_46;
}

// Returns whether this combination of handshake protocol and transport
// version is allowed. For example, {PROTOCOL_TLS1_3, QUIC_VERSION_43} is NOT
// allowed as TLS requires crypto frames which v43 does not support. Note that
// UnsupportedQuicVersion is a valid version.
QUIC_EXPORT_PRIVATE constexpr bool ParsedQuicVersionIsValid(
    HandshakeProtocol handshake_protocol,
    QuicTransportVersion transport_version) {
  bool transport_version_is_valid = false;
  constexpr QuicTransportVersion valid_transport_versions[] = {
      QUIC_VERSION_IETF_2_DRAFT_01,
      QUIC_VERSION_IETF_RFC_V1,
      QUIC_VERSION_IETF_DRAFT_29,
      QUIC_VERSION_50,
      QUIC_VERSION_46,
      QUIC_VERSION_43,
      QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
      QUIC_VERSION_UNSUPPORTED,
  };
  for (size_t i = 0; i < ABSL_ARRAYSIZE(valid_transport_versions); ++i) {
    if (transport_version == valid_transport_versions[i]) {
      transport_version_is_valid = true;
      break;
    }
  }
  if (!transport_version_is_valid) {
    return false;
  }
  switch (handshake_protocol) {
    case PROTOCOL_UNSUPPORTED:
      return transport_version == QUIC_VERSION_UNSUPPORTED;
    case PROTOCOL_QUIC_CRYPTO:
      return transport_version != QUIC_VERSION_UNSUPPORTED &&
             transport_version != QUIC_VERSION_RESERVED_FOR_NEGOTIATION &&
             transport_version != QUIC_VERSION_IETF_DRAFT_29 &&
             transport_version != QUIC_VERSION_IETF_RFC_V1 &&
             transport_version != QUIC_VERSION_IETF_2_DRAFT_01;
    case PROTOCOL_TLS1_3:
      return transport_version != QUIC_VERSION_UNSUPPORTED &&
             transport_version != QUIC_VERSION_50 &&
             QuicVersionUsesCryptoFrames(transport_version);
  }
  return false;
}

// A parsed QUIC version label which determines that handshake protocol
// and the transport version.
struct QUIC_EXPORT_PRIVATE ParsedQuicVersion {
  HandshakeProtocol handshake_protocol;
  QuicTransportVersion transport_version;

  constexpr ParsedQuicVersion(HandshakeProtocol handshake_protocol,
                              QuicTransportVersion transport_version)
      : handshake_protocol(handshake_protocol),
        transport_version(transport_version) {
    QUICHE_DCHECK(
        ParsedQuicVersionIsValid(handshake_protocol, transport_version))
        << QuicVersionToString(transport_version) << " "
        << HandshakeProtocolToString(handshake_protocol);
  }

  constexpr ParsedQuicVersion(const ParsedQuicVersion& other)
      : ParsedQuicVersion(other.handshake_protocol, other.transport_version) {}

  ParsedQuicVersion& operator=(const ParsedQuicVersion& other) {
    QUICHE_DCHECK(ParsedQuicVersionIsValid(other.handshake_protocol,
                                           other.transport_version))
        << QuicVersionToString(other.transport_version) << " "
        << HandshakeProtocolToString(other.handshake_protocol);
    if (this != &other) {
      handshake_protocol = other.handshake_protocol;
      transport_version = other.transport_version;
    }
    return *this;
  }

  bool operator==(const ParsedQuicVersion& other) const {
    return handshake_protocol == other.handshake_protocol &&
           transport_version == other.transport_version;
  }

  bool operator!=(const ParsedQuicVersion& other) const {
    return handshake_protocol != other.handshake_protocol ||
           transport_version != other.transport_version;
  }

  static constexpr ParsedQuicVersion V2Draft01() {
    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_2_DRAFT_01);
  }

  static constexpr ParsedQuicVersion RFCv1() {
    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_RFC_V1);
  }

  static constexpr ParsedQuicVersion Draft29() {
    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
  }

  static constexpr ParsedQuicVersion Q050() {
    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
  }

  static constexpr ParsedQuicVersion Q046() {
    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
  }

  static constexpr ParsedQuicVersion Q043() {
    return ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43);
  }

  static constexpr ParsedQuicVersion Unsupported() {
    return ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED);
  }

  static constexpr ParsedQuicVersion ReservedForNegotiation() {
    return ParsedQuicVersion(PROTOCOL_TLS1_3,
                             QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
  }

  // Returns whether our codebase understands this version. This should only be
  // called on valid versions, see ParsedQuicVersionIsValid. Assuming the
  // version is valid, IsKnown returns whether the version is not
  // UnsupportedQuicVersion.
  bool IsKnown() const;

  bool KnowsWhichDecrypterToUse() const;

  // Returns whether this version uses keys derived from the Connection ID for
  // ENCRYPTION_INITIAL keys (instead of NullEncrypter/NullDecrypter).
  bool UsesInitialObfuscators() const;

  // Indicates that this QUIC version does not have an enforced minimum value
  // for flow control values negotiated during the handshake.
  bool AllowsLowFlowControlLimits() const;

  // Returns whether header protection is used in this version of QUIC.
  bool HasHeaderProtection() const;

  // Returns whether this version supports IETF RETRY packets.
  bool SupportsRetry() const;

  // Returns true if this version sends variable length packet number in long
  // header.
  bool SendsVariableLengthPacketNumberInLongHeader() const;

  // Returns whether this version allows server connection ID lengths
  // that are not 64 bits.
  bool AllowsVariableLengthConnectionIds() const;

  // Returns whether this version supports client connection ID.
  bool SupportsClientConnectionIds() const;

  // Returns whether this version supports long header 8-bit encoded
  // connection ID lengths as described in draft-ietf-quic-invariants-06 and
  // draft-ietf-quic-transport-22.
  bool HasLengthPrefixedConnectionIds() const;

  // Returns whether this version supports IETF style anti-amplification limit,
  // i.e., server will send no more than FLAGS_quic_anti_amplification_factor
  // times received bytes until address can be validated.
  bool SupportsAntiAmplificationLimit() const;

  // Returns true if this version can send coalesced packets.
  bool CanSendCoalescedPackets() const;

  // Returns true if this version supports the old Google-style Alt-Svc
  // advertisement format.
  bool SupportsGoogleAltSvcFormat() const;

  // Returns true if |transport_version| uses IETF invariant headers.
  bool HasIetfInvariantHeader() const;

  // Returns true if |transport_version| supports MESSAGE frames.
  bool SupportsMessageFrames() const;

  // If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
  // Notable changes are:
  // * Headers stream no longer exists.
  // * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
  // * PUSH_PROMISE is moved to request stream.
  // * Unidirectional streams will have their first byte as a stream type.
  // * HEADERS frames are compressed using QPACK.
  // * DATA frame has frame headers.
  // * GOAWAY is moved to HTTP layer.
  bool UsesHttp3() const;

  // Returns whether the transport_version supports the variable length integer
  // length field as defined by IETF QUIC draft-13 and later.
  bool HasLongHeaderLengths() const;

  // Returns whether |transport_version| uses CRYPTO frames for the handshake
  // instead of stream 1.
  bool UsesCryptoFrames() const;

  // Returns whether |transport_version| makes use of IETF QUIC
  // frames or not.
  bool HasIetfQuicFrames() const;

  // Returns whether this version uses the legacy TLS extension codepoint.
  bool UsesLegacyTlsExtension() const;

  // Returns whether this version uses PROTOCOL_TLS1_3.
  bool UsesTls() const;

  // Returns whether this version uses PROTOCOL_QUIC_CRYPTO.
  bool UsesQuicCrypto() const;

  // Returns whether this version uses the QUICv2 Long Header Packet Types.
  bool UsesV2PacketTypes() const;

  // Returns true if this shares ALPN codes with RFCv1, and endpoints should
  // choose RFCv1 when presented with a v1 ALPN. Note that this is false for
  // RFCv1.
  bool AlpnDeferToRFCv1() const;
};

QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();

QUIC_EXPORT_PRIVATE ParsedQuicVersion QuicVersionReservedForNegotiation();

// Outer version used when encapsulating other packets using the Legacy Version
// Encapsulation feature.
QUIC_EXPORT_PRIVATE ParsedQuicVersion LegacyVersionForEncapsulation();

QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
                                             const ParsedQuicVersion& version);

using ParsedQuicVersionVector = std::vector<ParsedQuicVersion>;

QUIC_EXPORT_PRIVATE std::ostream& operator<<(
    std::ostream& os, const ParsedQuicVersionVector& versions);

// Representation of the on-the-wire QUIC version number. Will be written/read
// to the wire in network-byte-order.
using QuicVersionLabel = uint32_t;
using QuicVersionLabelVector = std::vector<QuicVersionLabel>;

// Constructs a version label from the 4 bytes such that the on-the-wire
// order will be: d, c, b, a.
QUIC_EXPORT_PRIVATE QuicVersionLabel MakeVersionLabel(uint8_t a, uint8_t b,
                                                      uint8_t c, uint8_t d);

QUIC_EXPORT_PRIVATE std::ostream& operator<<(
    std::ostream& os, const QuicVersionLabelVector& version_labels);

// This vector contains all crypto handshake protocols that are supported.
constexpr std::array<HandshakeProtocol, 2> SupportedHandshakeProtocols() {
  return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
}

constexpr std::array<ParsedQuicVersion, 6> SupportedVersions() {
  return {
      ParsedQuicVersion::V2Draft01(), ParsedQuicVersion::RFCv1(),
      ParsedQuicVersion::Draft29(),   ParsedQuicVersion::Q050(),
      ParsedQuicVersion::Q046(),      ParsedQuicVersion::Q043(),
  };
}

using QuicTransportVersionVector = std::vector<QuicTransportVersion>;

QUIC_EXPORT_PRIVATE std::ostream& operator<<(
    std::ostream& os, const QuicTransportVersionVector& transport_versions);

// Returns a vector of supported QUIC versions.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersions();

// Returns a vector of supported QUIC versions, with any versions disabled by
// flags excluded.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersions();

// Returns a vector of QUIC versions from |versions| which exclude any versions
// which are disabled by flags.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
FilterSupportedVersions(ParsedQuicVersionVector versions);

// Returns a subset of AllSupportedVersions() with
// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
// Deprecated; only to be used in components that do not yet support
// PROTOCOL_TLS1_3.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
AllSupportedVersionsWithQuicCrypto();

// Returns a subset of CurrentSupportedVersions() with
// handshake_protocol == PROTOCOL_QUIC_CRYPTO, in the same order.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
CurrentSupportedVersionsWithQuicCrypto();

// Returns a subset of AllSupportedVersions() with
// handshake_protocol == PROTOCOL_TLS1_3, in the same order.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector AllSupportedVersionsWithTls();

// Returns a subset of CurrentSupportedVersions() with handshake_protocol ==
// PROTOCOL_TLS1_3.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedVersionsWithTls();

// Returns a subset of CurrentSupportedVersions() using HTTP/3 at the HTTP
// layer.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector CurrentSupportedHttp3Versions();

// Returns QUIC version of |index| in result of |versions|. Returns
// UnsupportedQuicVersion() if |index| is out of bounds.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
ParsedVersionOfIndex(const ParsedQuicVersionVector& versions, int index);

// QuicVersionLabel is written to and read from the wire, but we prefer to use
// the more readable ParsedQuicVersion at other levels.
// Helper function which translates from a QuicVersionLabel to a
// ParsedQuicVersion.
QUIC_EXPORT_PRIVATE ParsedQuicVersion
ParseQuicVersionLabel(QuicVersionLabel version_label);

// Helper function that translates from a QuicVersionLabelVector to a
// ParsedQuicVersionVector.
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
ParseQuicVersionLabelVector(const QuicVersionLabelVector& version_labels);

// Parses a QUIC version string such as "Q043" or "T051". Also supports parsing
// ALPN such as "h3-29" or "h3-Q050". For PROTOCOL_QUIC_CRYPTO versions, also
// supports parsing numbers such as "46".
QUIC_EXPORT_PRIVATE ParsedQuicVersion
ParseQuicVersionString(absl::string_view version_string);

// Parses a comma-separated list of QUIC version strings. Supports parsing by
// label, ALPN and numbers for PROTOCOL_QUIC_CRYPTO. Skips unknown versions.
// For example: "h3-29,Q050,46".
QUIC_EXPORT_PRIVATE ParsedQuicVersionVector
ParseQuicVersionVectorString(absl::string_view versions_string);

// Constructs a QuicVersionLabel from the provided ParsedQuicVersion.
// QuicVersionLabel is written to and read from the wire, but we prefer to use
// the more readable ParsedQuicVersion at other levels.
// Helper function which translates from a ParsedQuicVersion to a
// QuicVersionLabel. Returns 0 if |parsed_version| is unsupported.
QUIC_EXPORT_PRIVATE QuicVersionLabel
CreateQuicVersionLabel(ParsedQuicVersion parsed_version);

// Constructs a QuicVersionLabelVector from the provided
// ParsedQuicVersionVector.
QUIC_EXPORT_PRIVATE QuicVersionLabelVector
CreateQuicVersionLabelVector(const ParsedQuicVersionVector& versions);

// Helper function which translates from a QuicVersionLabel to a string.
QUIC_EXPORT_PRIVATE std::string QuicVersionLabelToString(
    QuicVersionLabel version_label);

// Helper function which translates from a QuicVersionLabel string to a
// ParsedQuicVersion. The version label string must be of the form returned
// by QuicVersionLabelToString, for example, "00000001" or "Q046", but not
// "51303433" (the hex encoding of the Q064 version label). Returns
// the ParsedQuicVersion which matches the label or UnsupportedQuicVersion()
// otherwise.
QUIC_EXPORT_PRIVATE ParsedQuicVersion
ParseQuicVersionLabelString(absl::string_view version_label_string);

// Returns |separator|-separated list of string representations of
// QuicVersionLabel values in the supplied |version_labels| vector. The values
// after the (0-based) |skip_after_nth_version|'th are skipped.
QUIC_EXPORT_PRIVATE std::string QuicVersionLabelVectorToString(
    const QuicVersionLabelVector& version_labels, const std::string& separator,
    size_t skip_after_nth_version);

// Returns comma separated list of string representations of QuicVersionLabel
// values in the supplied |version_labels| vector.
QUIC_EXPORT_PRIVATE inline std::string QuicVersionLabelVectorToString(
    const QuicVersionLabelVector& version_labels) {
  return QuicVersionLabelVectorToString(version_labels, ",",
                                        std::numeric_limits<size_t>::max());
}

// Helper function which translates from a ParsedQuicVersion to a string.
// Returns strings corresponding to the on-the-wire tag.
QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionToString(
    ParsedQuicVersion version);

// Returns a vector of supported QUIC transport versions. DEPRECATED, use
// AllSupportedVersions instead.
QUIC_EXPORT_PRIVATE QuicTransportVersionVector AllSupportedTransportVersions();

// Returns comma separated list of string representations of
// QuicTransportVersion enum values in the supplied |versions| vector.
QUIC_EXPORT_PRIVATE std::string QuicTransportVersionVectorToString(
    const QuicTransportVersionVector& versions);

// Returns comma separated list of string representations of ParsedQuicVersion
// values in the supplied |versions| vector.
QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
    const ParsedQuicVersionVector& versions);

// Returns |separator|-separated list of string representations of
// ParsedQuicVersion values in the supplied |versions| vector. The values after
// the (0-based) |skip_after_nth_version|'th are skipped.
QUIC_EXPORT_PRIVATE std::string ParsedQuicVersionVectorToString(
    const ParsedQuicVersionVector& versions, const std::string& separator,
    size_t skip_after_nth_version);

// Returns comma separated list of string representations of ParsedQuicVersion
// values in the supplied |versions| vector.
QUIC_EXPORT_PRIVATE inline std::string ParsedQuicVersionVectorToString(
    const ParsedQuicVersionVector& versions) {
  return ParsedQuicVersionVectorToString(versions, ",",
                                         std::numeric_limits<size_t>::max());
}

// Returns true if |transport_version| uses IETF invariant headers.
QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfInvariantHeader(
    QuicTransportVersion transport_version) {
  return transport_version > QUIC_VERSION_43;
}

// Returns true if |transport_version| supports MESSAGE frames.
QUIC_EXPORT_PRIVATE constexpr bool VersionSupportsMessageFrames(
    QuicTransportVersion transport_version) {
  // MESSAGE frames were added in version 45.
  return transport_version > QUIC_VERSION_43;
}

// If true, HTTP/3 instead of gQUIC will be used at the HTTP layer.
// Notable changes are:
// * Headers stream no longer exists.
// * PRIORITY, HEADERS are moved from headers stream to HTTP/3 control stream.
// * PUSH_PROMISE is moved to request stream.
// * Unidirectional streams will have their first byte as a stream type.
// * HEADERS frames are compressed using QPACK.
// * DATA frame has frame headers.
// * GOAWAY is moved to HTTP layer.
QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3(
    QuicTransportVersion transport_version) {
  return transport_version >= QUIC_VERSION_IETF_DRAFT_29;
}

// Returns whether the transport_version supports the variable length integer
// length field as defined by IETF QUIC draft-13 and later.
QUIC_EXPORT_PRIVATE constexpr bool QuicVersionHasLongHeaderLengths(
    QuicTransportVersion transport_version) {
  // Long header lengths were added in version 49.
  return transport_version > QUIC_VERSION_46;
}

// Returns whether |transport_version| makes use of IETF QUIC
// frames or not.
QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames(
    QuicTransportVersion transport_version) {
  return VersionUsesHttp3(transport_version);
}

// Returns whether this version supports long header 8-bit encoded
// connection ID lengths as described in draft-ietf-quic-invariants-06 and
// draft-ietf-quic-transport-22.
QUIC_EXPORT_PRIVATE bool VersionHasLengthPrefixedConnectionIds(
    QuicTransportVersion transport_version);

// Returns true if this version supports the old Google-style Alt-Svc
// advertisement format.
QUIC_EXPORT_PRIVATE bool VersionSupportsGoogleAltSvcFormat(
    QuicTransportVersion transport_version);

// Returns whether this version allows server connection ID lengths that are
// not 64 bits.
QUIC_EXPORT_PRIVATE bool VersionAllowsVariableLengthConnectionIds(
    QuicTransportVersion transport_version);

// Returns whether this version label supports long header 4-bit encoded
// connection ID lengths as described in draft-ietf-quic-invariants-05 and
// draft-ietf-quic-transport-21.
QUIC_EXPORT_PRIVATE bool QuicVersionLabelUses4BitConnectionIdLength(
    QuicVersionLabel version_label);

// Returns the ALPN string to use in TLS for this version of QUIC.
QUIC_EXPORT_PRIVATE std::string AlpnForVersion(
    ParsedQuicVersion parsed_version);

// Initializes support for the provided IETF draft version by setting the
// correct flags.
QUIC_EXPORT_PRIVATE void QuicVersionInitializeSupportForIetfDraft();

// Configures the flags required to enable support for this version of QUIC.
QUIC_EXPORT_PRIVATE void QuicEnableVersion(const ParsedQuicVersion& version);

// Configures the flags required to disable support for this version of QUIC.
QUIC_EXPORT_PRIVATE void QuicDisableVersion(const ParsedQuicVersion& version);

// Returns whether support for this version of QUIC is currently enabled.
QUIC_EXPORT_PRIVATE bool QuicVersionIsEnabled(const ParsedQuicVersion& version);

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_VERSIONS_H_
