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

// Structured data for message types in draft-ietf-moq-transport-02.

#ifndef QUICHE_QUIC_MOQT_MOQT_MESSAGES_H_
#define QUICHE_QUIC_MOQT_MOQT_MESSAGES_H_

#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/container/btree_map.h"
#include "absl/container/inlined_vector.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_types.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/moqt/moqt_priority.h"
#include "quiche/common/platform/api/quiche_bug_tracker.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/web_transport/web_transport.h"

namespace moqt {

inline constexpr quic::ParsedQuicVersionVector GetMoqtSupportedQuicVersions() {
  return quic::ParsedQuicVersionVector{quic::ParsedQuicVersion::RFCv1()};
}

enum class MoqtVersion : uint64_t {
  kDraft11 = 0xff00000b,
  kUnrecognizedVersionForTests = 0xfe0000ff,
};

inline constexpr MoqtVersion kDefaultMoqtVersion = MoqtVersion::kDraft11;
inline constexpr uint64_t kDefaultInitialMaxRequestId = 100;
// TODO(martinduke): Implement an auth token cache.
inline constexpr uint64_t kDefaultMaxAuthTokenCacheSize = 0;
inline constexpr uint64_t kMinNamespaceElements = 1;
inline constexpr uint64_t kMaxNamespaceElements = 32;
inline constexpr size_t kMaxFullTrackNameSize = 1024;

struct QUICHE_EXPORT MoqtSessionParameters {
  // TODO: support multiple versions.
  MoqtSessionParameters() = default;
  explicit MoqtSessionParameters(quic::Perspective perspective)
      : perspective(perspective), using_webtrans(true) {}
  MoqtSessionParameters(quic::Perspective perspective, std::string path)
      : perspective(perspective),
        using_webtrans(false),
        path(std::move(path)) {}
  MoqtSessionParameters(quic::Perspective perspective, std::string path,
                        uint64_t max_request_id)
      : perspective(perspective),
        using_webtrans(true),
        path(std::move(path)),
        max_request_id(max_request_id) {}
  MoqtSessionParameters(quic::Perspective perspective, uint64_t max_request_id)
      : perspective(perspective), max_request_id(max_request_id) {}
  bool operator==(const MoqtSessionParameters& other) {
    return version == other.version &&
           deliver_partial_objects == other.deliver_partial_objects &&
           perspective == other.perspective &&
           using_webtrans == other.using_webtrans && path == other.path &&
           max_request_id == other.max_request_id &&
           max_auth_token_cache_size == other.max_auth_token_cache_size &&
           support_object_acks == other.support_object_acks;
  }

  MoqtVersion version = kDefaultMoqtVersion;
  bool deliver_partial_objects = false;
  quic::Perspective perspective = quic::Perspective::IS_SERVER;
  bool using_webtrans = true;
  std::string path = "";
  uint64_t max_request_id = kDefaultInitialMaxRequestId;
  uint64_t max_auth_token_cache_size = kDefaultMaxAuthTokenCacheSize;
  bool support_object_acks = false;
};

// The maximum length of a message, excluding any OBJECT payload. This prevents
// DoS attack via forcing the parser to buffer a large message (OBJECT payloads
// are not buffered by the parser).
inline constexpr size_t kMaxMessageHeaderSize = 2048;

enum class QUICHE_EXPORT MoqtDataStreamType : uint64_t {
  kStreamHeaderSubgroup = 0x04,
  kStreamHeaderFetch = 0x05,

  // Currently QUICHE-specific.  All data on a kPadding stream is ignored.
  kPadding = 0x26d3,
};

enum class QUICHE_EXPORT MoqtDatagramType : uint64_t {
  kObject = 0x01,
  kObjectStatus = 0x02,
};

enum class QUICHE_EXPORT MoqtMessageType : uint64_t {
  kSubscribeUpdate = 0x02,
  kSubscribe = 0x03,
  kSubscribeOk = 0x04,
  kSubscribeError = 0x05,
  kAnnounce = 0x06,
  kAnnounceOk = 0x7,
  kAnnounceError = 0x08,
  kUnannounce = 0x09,
  kUnsubscribe = 0x0a,
  kSubscribeDone = 0x0b,
  kAnnounceCancel = 0x0c,
  kTrackStatusRequest = 0x0d,
  kTrackStatus = 0x0e,
  kGoAway = 0x10,
  kSubscribeAnnounces = 0x11,
  kSubscribeAnnouncesOk = 0x12,
  kSubscribeAnnouncesError = 0x13,
  kUnsubscribeAnnounces = 0x14,
  kMaxRequestId = 0x15,
  kFetch = 0x16,
  kFetchCancel = 0x17,
  kFetchOk = 0x18,
  kFetchError = 0x19,
  kRequestsBlocked = 0x1a,
  kClientSetup = 0x20,
  kServerSetup = 0x21,

  // QUICHE-specific extensions.

  // kObjectAck (OACK for short) is a frame used by the receiver indicating that
  // it has received and processed the specified object.
  kObjectAck = 0x3184,
};

enum class QUICHE_EXPORT MoqtError : uint64_t {
  kNoError = 0x0,
  kInternalError = 0x1,
  kUnauthorized = 0x2,
  kProtocolViolation = 0x3,
  kInvalidRequestId = 0x4,
  kDuplicateTrackAlias = 0x5,
  kKeyValueFormattingError = 0x6,
  kTooManyRequests = 0x7,
  kInvalidPath = 0x8,
  kMalformedPath = 0x9,
  kGoawayTimeout = 0x10,
  kControlMessageTimeout = 0x11,
  kDataStreamTimeout = 0x12,
  kAuthTokenCacheOverflow = 0x13,
  kDuplicateAuthTokenAlias = 0x14,
  kVersionNegotiationFailed = 0x15,
};

// Error codes used by MoQT to reset streams.
// TODO: update with spec-defined error codes once those are available, see
// <https://github.com/moq-wg/moq-transport/issues/481>.
inline constexpr webtransport::StreamErrorCode kResetCodeUnknown = 0x00;
inline constexpr webtransport::StreamErrorCode kResetCodeSubscriptionGone =
    0x01;
inline constexpr webtransport::StreamErrorCode kResetCodeTimedOut = 0x02;

enum class QUICHE_EXPORT SetupParameter : uint64_t {
  kPath = 0x1,
  kMaxRequestId = 0x2,
  kMaxAuthTokenCacheSize = 0x4,

  // QUICHE-specific extensions.
  // Indicates support for OACK messages.
  kSupportObjectAcks = 0xbbf1438,
};

enum class QUICHE_EXPORT VersionSpecificParameter : uint64_t {
  kAuthorizationToken = 0x1,
  kDeliveryTimeout = 0x2,
  kMaxCacheDuration = 0x4,

  // QUICHE-specific extensions.
  kOackWindowSize = 0xbbf1438,
};

enum AuthTokenType : uint64_t {
  kOutOfBand = 0x0,

  kMaxAuthTokenType = 0x0,
};

enum AuthTokenAliasType : uint64_t {
  kDelete = 0x0,
  kRegister = 0x1,
  kUseAlias = 0x2,
  kUseValue = 0x3,

  kMaxValue = 0x3,
};

struct AuthToken {
  AuthToken(AuthTokenType token_type, absl::string_view token)
      : type(token_type), token(token) {}
  bool operator==(const AuthToken& other) const {
    return type == other.type && token == other.token;
  }
  AuthTokenType type;
  std::string token;
};

struct VersionSpecificParameters {
  VersionSpecificParameters() = default;
  // Likely parameter combinations.
  VersionSpecificParameters(quic::QuicTimeDelta delivery_timeout,
                            quic::QuicTimeDelta max_cache_duration)
      : delivery_timeout(delivery_timeout),
        max_cache_duration(max_cache_duration) {}
  VersionSpecificParameters(AuthTokenType token_type, absl::string_view token) {
    authorization_token.emplace_back(token_type, token);
  };
  VersionSpecificParameters(quic::QuicTimeDelta delivery_timeout,
                            AuthTokenType token_type, absl::string_view token)
      : delivery_timeout(delivery_timeout) {
    authorization_token.emplace_back(token_type, token);
  }

  // TODO(martinduke): Turn auth_token into structured data.
  std::vector<AuthToken> authorization_token;
  quic::QuicTimeDelta delivery_timeout = quic::QuicTimeDelta::Infinite();
  quic::QuicTimeDelta max_cache_duration = quic::QuicTimeDelta::Infinite();
  std::optional<quic::QuicTimeDelta> oack_window_size;

  bool operator==(const VersionSpecificParameters& other) const {
    return authorization_token == other.authorization_token &&
           delivery_timeout == other.delivery_timeout &&
           max_cache_duration == other.max_cache_duration &&
           oack_window_size == other.oack_window_size;
  }
};

// Used for SUBSCRIBE_ERROR, ANNOUNCE_ERROR, ANNOUNCE_CANCEL,
// SUBSCRIBE_ANNOUNCES_ERROR, and FETCH_ERROR.
enum class QUICHE_EXPORT RequestErrorCode : uint64_t {
  kInternalError = 0x0,
  kUnauthorized = 0x1,
  kTimeout = 0x2,
  kNotSupported = 0x3,
  kTrackDoesNotExist = 0x4,          // SUBSCRIBE_ERROR and FETCH_ERROR only.
  kUninterested = 0x4,               // ANNOUNCE_ERROR and ANNOUNCE_CANCEL only.
  kNamespacePrefixUnknown = 0x4,     // SUBSCRIBE_ANNOUNCES_ERROR only.
  kInvalidRange = 0x5,               // SUBSCRIBE_ERROR and FETCH_ERROR only.
  kNamespacePrefixOverlap = 0x5,     // SUBSCRIBE_ANNOUNCES_ERROR only.
  kRetryTrackAlias = 0x6,            // SUBSCRIBE_ERROR only.
  kNoObjects = 0x6,                  // FETCH_ERROR only.
  kInvalidJoiningSubscribeId = 0x7,  // FETCH_ERROR only.
  kMalformedAuthToken = 0x10,
  kUnknownAuthTokenAlias = 0x11,
  kExpiredAuthToken = 0x12,
};

struct MoqtSubscribeErrorReason {
  RequestErrorCode error_code;
  std::string reason_phrase;
};
using MoqtAnnounceErrorReason = MoqtSubscribeErrorReason;

class TrackNamespace {
 public:
  explicit TrackNamespace(absl::Span<const absl::string_view> elements);
  explicit TrackNamespace(
      std::initializer_list<const absl::string_view> elements)
      : TrackNamespace(absl::Span<const absl::string_view>(
            std::data(elements), std::size(elements))) {}
  explicit TrackNamespace(absl::string_view ns) : TrackNamespace({ns}) {}
  TrackNamespace() : TrackNamespace({}) {}

  bool IsValid() const {
    return !tuple_.empty() && tuple_.size() <= kMaxNamespaceElements &&
           length_ <= kMaxFullTrackNameSize;
  }
  bool InNamespace(const TrackNamespace& other) const;
  // Check if adding an element will exceed limits, without triggering a
  // bug. Useful for the parser, which has to be robust to malformed data.
  bool CanAddElement(absl::string_view element) {
    return (tuple_.size() < kMaxNamespaceElements &&
            length_ + element.length() <= kMaxFullTrackNameSize);
  }
  void AddElement(absl::string_view element);
  std::string ToString() const;
  // Returns the number of elements in the tuple.
  size_t number_of_elements() const { return tuple_.size(); }
  // Returns the sum of the lengths of all elements in the tuple.
  size_t total_length() const { return length_; }
  bool operator==(const TrackNamespace& other) const;
  bool operator<(const TrackNamespace& other) const;
  const std::vector<std::string>& tuple() const { return tuple_; }

  template <typename H>
  friend H AbslHashValue(H h, const TrackNamespace& m) {
    return H::combine(std::move(h), m.tuple_);
  }
  template <typename Sink>
  friend void AbslStringify(Sink& sink, const TrackNamespace& track_namespace) {
    sink.Append(track_namespace.ToString());
  }

 private:
  std::vector<std::string> tuple_;
  size_t length_ = 0;  // size in bytes.
};

class FullTrackName {
 public:
  FullTrackName(absl::string_view ns, absl::string_view name)
      : namespace_(ns), name_(name) {
    QUICHE_BUG_IF(Moqt_full_track_name_too_large_01, !IsValid())
        << "Constructing a Full Track Name that is too large.";
  }
  FullTrackName(TrackNamespace ns, absl::string_view name)
      : namespace_(ns), name_(name) {
    QUICHE_BUG_IF(Moqt_full_track_name_too_large_02, !IsValid())
        << "Constructing a Full Track Name that is too large.";
  }
  FullTrackName() = default;

  bool IsValid() const {
    return namespace_.IsValid() && length() <= kMaxFullTrackNameSize;
  }
  const TrackNamespace& track_namespace() const { return namespace_; }
  TrackNamespace& track_namespace() { return namespace_; }
  absl::string_view name() const { return name_; }
  void AddElement(absl::string_view element) {
    return namespace_.AddElement(element);
  }
  std::string ToString() const {
    return absl::StrCat(namespace_.ToString(), "::", name_);
  }
  // Check if the name will exceed limits, without triggering a bug. Useful for
  // the parser, which has to be robust to malformed data.
  bool CanAddName(absl::string_view name) {
    return (namespace_.total_length() + name.length() <= kMaxFullTrackNameSize);
  }
  void set_name(absl::string_view name);
  size_t length() const { return namespace_.total_length() + name_.length(); }
  bool operator==(const FullTrackName& other) const {
    return name_ == other.name_ && namespace_ == other.namespace_;
  }
  bool operator<(const FullTrackName& other) const {
    return namespace_ < other.namespace_ ||
           (namespace_ == other.namespace_ && name_ < other.name_);
  }
  template <typename H>
  friend H AbslHashValue(H h, const FullTrackName& m) {
    return H::combine(std::move(h), m.namespace_.tuple(), m.name_);
  }
  template <typename Sink>
  friend void AbslStringify(Sink& sink, const FullTrackName& full_track_name) {
    sink.Append(full_track_name.ToString());
  }

 private:
  TrackNamespace namespace_;
  std::string name_ = "";
};

// These are absolute sequence numbers.
struct Location {
  uint64_t group;
  uint64_t subgroup;
  uint64_t object;
  Location() : Location(0, 0) {}
  // There is a lot of code from before subgroups. Assume there's one subgroup
  // with ID 0 per group.
  Location(uint64_t group, uint64_t object) : Location(group, 0, object) {}
  Location(uint64_t group, uint64_t subgroup, uint64_t object)
      : group(group), subgroup(subgroup), object(object) {}
  bool operator==(const Location& other) const {
    return group == other.group && object == other.object;
  }
  // These are temporal ordering comparisons, so subgroup ID doesn't matter.
  bool operator<(const Location& other) const {
    return group < other.group ||
           (group == other.group && object < other.object);
  }
  bool operator<=(const Location& other) const {
    return (group < other.group ||
            (group == other.group && object <= other.object));
  }
  bool operator>(const Location& other) const { return !(*this <= other); }
  Location& operator=(Location other) {
    group = other.group;
    subgroup = other.subgroup;
    object = other.object;
    return *this;
  }
  Location next() const { return Location{group, subgroup, object + 1}; }
  template <typename H>
  friend H AbslHashValue(H h, const Location& m);

  template <typename Sink>
  friend void AbslStringify(Sink& sink, const Location& sequence) {
    absl::Format(&sink, "(%d; %d)", sequence.group, sequence.object);
  }
};

struct SubgroupPriority {
  uint8_t publisher_priority = 0xf0;
  uint64_t subgroup_id = 0;

  bool operator==(const SubgroupPriority& other) const {
    return publisher_priority == other.publisher_priority &&
           subgroup_id == other.subgroup_id;
  }
  bool operator<(const SubgroupPriority& other) const {
    return publisher_priority < other.publisher_priority ||
           (publisher_priority == other.publisher_priority &&
            subgroup_id < other.subgroup_id);
  }
  bool operator<=(const SubgroupPriority& other) const {
    return (publisher_priority < other.publisher_priority ||
            (publisher_priority == other.publisher_priority &&
             subgroup_id <= other.subgroup_id));
  }
};

template <typename H>
H AbslHashValue(H h, const Location& m) {
  return H::combine(std::move(h), m.group, m.object);
}

// Encodes a list of key-value pairs common to both parameters and extensions.
// If the key is odd, it is a length-prefixed string (which may encode further
// item-specific structure). If the key is even, it is a varint.
// This class does not interpret the semantic meaning of the keys and values,
// although it does accept various uint64_t-based enums to reduce the burden of
// casting on the caller.
class KeyValuePairList {
 public:
  KeyValuePairList() = default;
  size_t size() const { return integer_map_.size() + string_map_.size(); }
  void insert(VersionSpecificParameter key, uint64_t value) {
    insert(static_cast<uint64_t>(key), value);
  }
  void insert(SetupParameter key, uint64_t value) {
    insert(static_cast<uint64_t>(key), value);
  }
  void insert(VersionSpecificParameter key, absl::string_view value) {
    insert(static_cast<uint64_t>(key), value);
  }
  void insert(SetupParameter key, absl::string_view value) {
    insert(static_cast<uint64_t>(key), value);
  }
  void insert(uint64_t key, absl::string_view value);
  void insert(uint64_t key, uint64_t value);
  size_t count(VersionSpecificParameter key) const {
    return count(static_cast<uint64_t>(key));
  }
  size_t count(SetupParameter key) const {
    return count(static_cast<uint64_t>(key));
  }
  bool contains(VersionSpecificParameter key) const {
    return contains(static_cast<uint64_t>(key));
  }
  bool contains(SetupParameter key) const {
    return contains(static_cast<uint64_t>(key));
  }
  // If either of these callbacks returns false, ForEach will return early.
  using IntCallback = quiche::UnretainedCallback<bool(uint64_t, uint64_t)>;
  using StringCallback =
      quiche::UnretainedCallback<bool(uint64_t, absl::string_view)>;
  // Iterates through the whole list, and executes int_callback for each integer
  // value and string_callback for each string value.
  bool ForEach(IntCallback int_callback, StringCallback string_callback) const {
    for (const auto& [key, value] : integer_map_) {
      if (!int_callback(key, value)) {
        return false;
      }
    }
    for (const auto& [key, value] : string_map_) {
      if (!string_callback(key, value)) {
        return false;
      }
    }
    return true;
  }
  std::vector<uint64_t> GetIntegers(VersionSpecificParameter key) const {
    return GetIntegers(static_cast<uint64_t>(key));
  }
  std::vector<uint64_t> GetIntegers(SetupParameter key) const {
    return GetIntegers(static_cast<uint64_t>(key));
  }
  std::vector<absl::string_view> GetStrings(
      VersionSpecificParameter key) const {
    return GetStrings(static_cast<uint64_t>(key));
  }
  std::vector<absl::string_view> GetStrings(SetupParameter key) const {
    return GetStrings(static_cast<uint64_t>(key));
  }
  void clear() {
    integer_map_.clear();
    string_map_.clear();
  }

 private:
  size_t count(uint64_t key) const;
  bool contains(uint64_t key) const;
  std::vector<uint64_t> GetIntegers(uint64_t key) const;
  std::vector<absl::string_view> GetStrings(uint64_t key) const;
  absl::btree_multimap<uint64_t, uint64_t> integer_map_;
  absl::btree_multimap<uint64_t, std::string> string_map_;
};

// TODO(martinduke): Collapse both Setup messages into MoqtSessionParameters.
struct QUICHE_EXPORT MoqtClientSetup {
  std::vector<MoqtVersion> supported_versions;
  MoqtSessionParameters parameters;
};

struct QUICHE_EXPORT MoqtServerSetup {
  MoqtVersion selected_version;
  MoqtSessionParameters parameters;
};

// These codes do not appear on the wire.
enum class QUICHE_EXPORT MoqtForwardingPreference {
  kSubgroup,
  kDatagram,
};

enum class QUICHE_EXPORT MoqtObjectStatus : uint64_t {
  kNormal = 0x0,
  kObjectDoesNotExist = 0x1,
  kGroupDoesNotExist = 0x2,
  kEndOfGroup = 0x3,
  kEndOfTrackAndGroup = 0x4,
  kEndOfTrack = 0x5,
  kInvalidObjectStatus = 0x6,
};

MoqtObjectStatus IntegerToObjectStatus(uint64_t integer);

// The data contained in every Object message, although the message type
// implies some of the values.
struct QUICHE_EXPORT MoqtObject {
  uint64_t track_alias;  // For FETCH, this is the subscribe ID.
  uint64_t group_id;
  uint64_t object_id;
  MoqtPriority publisher_priority;
  std::string extension_headers;  // Raw, unparsed extension headers.
  MoqtObjectStatus object_status;
  std::optional<uint64_t> subgroup_id;
  uint64_t payload_length;
};

enum class QUICHE_EXPORT MoqtFilterType : uint64_t {
  kNone = 0x0,
  kNextGroupStart = 0x1,
  kLatestObject = 0x2,
  kAbsoluteStart = 0x3,
  kAbsoluteRange = 0x4,
};

struct QUICHE_EXPORT MoqtSubscribe {
  uint64_t request_id;
  uint64_t track_alias;
  FullTrackName full_track_name;
  MoqtPriority subscriber_priority;
  std::optional<MoqtDeliveryOrder> group_order;
  bool forward;
  MoqtFilterType filter_type;
  std::optional<Location> start;
  std::optional<uint64_t> end_group;
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtSubscribeOk {
  uint64_t request_id;
  // The message uses ms, but expires is in us.
  quic::QuicTimeDelta expires = quic::QuicTimeDelta::FromMilliseconds(0);
  MoqtDeliveryOrder group_order;
  // If ContextExists on the wire is zero, largest_id has no value.
  std::optional<Location> largest_location;
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtSubscribeError {
  uint64_t request_id;
  RequestErrorCode error_code;
  std::string reason_phrase;
  uint64_t track_alias;
};

struct QUICHE_EXPORT MoqtUnsubscribe {
  uint64_t subscribe_id;
};

enum class QUICHE_EXPORT SubscribeDoneCode : uint64_t {
  kInternalError = 0x0,
  kUnauthorized = 0x1,
  kTrackEnded = 0x2,
  kSubscriptionEnded = 0x3,
  kGoingAway = 0x4,
  kExpired = 0x5,
  kTooFarBehind = 0x6,
};

struct QUICHE_EXPORT MoqtSubscribeDone {
  uint64_t subscribe_id;
  SubscribeDoneCode status_code;
  uint64_t stream_count;
  std::string reason_phrase;
};

struct QUICHE_EXPORT MoqtSubscribeUpdate {
  uint64_t request_id;
  Location start;
  std::optional<uint64_t> end_group;
  MoqtPriority subscriber_priority;
  bool forward;
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtAnnounce {
  TrackNamespace track_namespace;
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtAnnounceOk {
  TrackNamespace track_namespace;
};

struct QUICHE_EXPORT MoqtAnnounceError {
  TrackNamespace track_namespace;
  RequestErrorCode error_code;
  std::string reason_phrase;
};

struct QUICHE_EXPORT MoqtUnannounce {
  TrackNamespace track_namespace;
};

enum class QUICHE_EXPORT MoqtTrackStatusCode : uint64_t {
  kInProgress = 0x0,
  kDoesNotExist = 0x1,
  kNotYetBegun = 0x2,
  kFinished = 0x3,
  kStatusNotAvailable = 0x4,
};

inline bool DoesTrackStatusImplyHavingData(MoqtTrackStatusCode code) {
  switch (code) {
    case MoqtTrackStatusCode::kInProgress:
    case MoqtTrackStatusCode::kFinished:
      return true;
    case MoqtTrackStatusCode::kDoesNotExist:
    case MoqtTrackStatusCode::kNotYetBegun:
    case MoqtTrackStatusCode::kStatusNotAvailable:
      return false;
  }
  return false;
}

struct QUICHE_EXPORT MoqtTrackStatus {
  FullTrackName full_track_name;
  MoqtTrackStatusCode status_code;
  uint64_t last_group;
  uint64_t last_object;
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtAnnounceCancel {
  TrackNamespace track_namespace;
  RequestErrorCode error_code;
  std::string reason_phrase;
};

struct QUICHE_EXPORT MoqtTrackStatusRequest {
  FullTrackName full_track_name;
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtGoAway {
  std::string new_session_uri;
};

struct QUICHE_EXPORT MoqtSubscribeAnnounces {
  TrackNamespace track_namespace;
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtSubscribeAnnouncesOk {
  TrackNamespace track_namespace;
};

struct QUICHE_EXPORT MoqtSubscribeAnnouncesError {
  TrackNamespace track_namespace;
  RequestErrorCode error_code;
  std::string reason_phrase;
};

struct QUICHE_EXPORT MoqtUnsubscribeAnnounces {
  TrackNamespace track_namespace;
};

struct QUICHE_EXPORT MoqtMaxRequestId {
  uint64_t max_request_id;
};

enum class QUICHE_EXPORT FetchType : uint64_t {
  kStandalone = 0x1,
  kJoining = 0x2,
};

struct JoiningFetch {
  JoiningFetch(uint64_t joining_subscribe_id, uint64_t preceding_group_offset)
      : joining_subscribe_id(joining_subscribe_id),
        preceding_group_offset(preceding_group_offset) {}
  uint64_t joining_subscribe_id;
  uint64_t preceding_group_offset;
};

struct QUICHE_EXPORT MoqtFetch {
  uint64_t fetch_id;
  MoqtPriority subscriber_priority;
  std::optional<MoqtDeliveryOrder> group_order;
  // If joining_fetch has a value, then the parser will not populate the name
  // and ranges. The session will populate them instead.
  std::optional<JoiningFetch> joining_fetch;
  FullTrackName full_track_name;
  Location start_object;  // subgroup is ignored
  uint64_t end_group;
  std::optional<uint64_t> end_object;
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtFetchCancel {
  uint64_t subscribe_id;
};

struct QUICHE_EXPORT MoqtFetchOk {
  uint64_t subscribe_id;
  MoqtDeliveryOrder group_order;
  Location largest_id;  // subgroup is ignored
  VersionSpecificParameters parameters;
};

struct QUICHE_EXPORT MoqtFetchError {
  uint64_t subscribe_id;
  RequestErrorCode error_code;
  std::string reason_phrase;
};

struct QUICHE_EXPORT MoqtRequestsBlocked {
  uint64_t max_request_id;
};

// All of the four values in this message are encoded as varints.
// `delta_from_deadline` is encoded as an absolute value, with the lowest bit
// indicating the sign (0 if positive).
struct QUICHE_EXPORT MoqtObjectAck {
  uint64_t subscribe_id;
  uint64_t group_id;
  uint64_t object_id;
  // Positive if the object has been received before the deadline.
  quic::QuicTimeDelta delta_from_deadline = quic::QuicTimeDelta::Zero();
};

RequestErrorCode StatusToRequestErrorCode(absl::Status status);
absl::StatusCode RequestErrorCodeToStatusCode(RequestErrorCode error_code);
absl::Status RequestErrorCodeToStatus(RequestErrorCode error_code,
                                      absl::string_view reason_phrase);

// Returns an error if the parameters are malformed or otherwise violate the
// spec. |perspective| is the consumer of the message, not the sender.
MoqtError ValidateSetupParameters(const KeyValuePairList& parameters,
                                  bool webtrans, quic::Perspective perspective);
// Returns false if the parameters contain a protocol violation, or a
// parameter cannot be in |message type|. Does not validate the internal
// structure of Authorization Token values.
bool ValidateVersionSpecificParameters(const KeyValuePairList& parameters,
                                       MoqtMessageType message_type);

std::string MoqtMessageTypeToString(MoqtMessageType message_type);
std::string MoqtDataStreamTypeToString(MoqtDataStreamType type);
std::string MoqtDatagramTypeToString(MoqtDatagramType type);

std::string MoqtForwardingPreferenceToString(
    MoqtForwardingPreference preference);

absl::Status MoqtStreamErrorToStatus(webtransport::StreamErrorCode error_code,
                                     absl::string_view reason_phrase);

}  // namespace moqt

#endif  // QUICHE_QUIC_MOQT_MOQT_MESSAGES_H_
