// Copyright 2016 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.

#ifndef QUICHE_HTTP2_HTTP2_STRUCTURES_H_
#define QUICHE_HTTP2_HTTP2_STRUCTURES_H_

// Defines structs for various fixed sized structures in HTTP/2.
//
// Those structs with multiple fields have constructors that take arguments in
// the same order as their encoding (which may be different from their order
// in the struct). For single field structs, use aggregate initialization if
// desired, e.g.:
//
//   Http2RstStreamFields var{Http2ErrorCode::ENHANCE_YOUR_CALM};
// or:
//   SomeFunc(Http2RstStreamFields{Http2ErrorCode::ENHANCE_YOUR_CALM});
//
// Each struct includes a static method EncodedSize which returns the number
// of bytes of the encoding.
//
// With the exception of Http2FrameHeader, all the types are named
// Http2<X>Fields, where X is the title-case form of the frame which always
// includes the fields; the "always" is to cover the case of the PRIORITY frame;
// its fields optionally appear in the HEADERS frame, but the struct is called
// Http2PriorityFields.

#include <stddef.h>

#include <cstdint>
#include <ostream>
#include <string>

#include "quiche/http2/http2_constants.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace http2 {

struct QUICHE_EXPORT Http2FrameHeader {
  Http2FrameHeader() {}
  Http2FrameHeader(uint32_t payload_length, Http2FrameType type, uint8_t flags,
                   uint32_t stream_id)
      : payload_length(payload_length),
        stream_id(stream_id),
        type(type),
        flags(flags) {
    QUICHE_DCHECK_LT(payload_length, static_cast<uint32_t>(1 << 24))
        << "Payload Length is only a 24 bit field\n"
        << ToString();
  }

  static constexpr size_t EncodedSize() { return 9; }

  // Keep the current value of those flags that are in
  // valid_flags, and clear all the others.
  void RetainFlags(uint8_t valid_flags) { flags = (flags & valid_flags); }

  // Returns true if any of the flags in flag_mask are set,
  // otherwise false.
  bool HasAnyFlags(uint8_t flag_mask) const { return 0 != (flags & flag_mask); }

  // Is the END_STREAM flag set?
  bool IsEndStream() const {
    QUICHE_DCHECK(type == Http2FrameType::DATA ||
                  type == Http2FrameType::HEADERS)
        << ToString();
    return (flags & Http2FrameFlag::END_STREAM) != 0;
  }

  // Is the ACK flag set?
  bool IsAck() const {
    QUICHE_DCHECK(type == Http2FrameType::SETTINGS ||
                  type == Http2FrameType::PING)
        << ToString();
    return (flags & Http2FrameFlag::ACK) != 0;
  }

  // Is the END_HEADERS flag set?
  bool IsEndHeaders() const {
    QUICHE_DCHECK(type == Http2FrameType::HEADERS ||
                  type == Http2FrameType::PUSH_PROMISE ||
                  type == Http2FrameType::CONTINUATION)
        << ToString();
    return (flags & Http2FrameFlag::END_HEADERS) != 0;
  }

  // Is the PADDED flag set?
  bool IsPadded() const {
    QUICHE_DCHECK(type == Http2FrameType::DATA ||
                  type == Http2FrameType::HEADERS ||
                  type == Http2FrameType::PUSH_PROMISE)
        << ToString();
    return (flags & Http2FrameFlag::PADDED) != 0;
  }

  // Is the PRIORITY flag set?
  bool HasPriority() const {
    QUICHE_DCHECK_EQ(type, Http2FrameType::HEADERS) << ToString();
    return (flags & Http2FrameFlag::PRIORITY) != 0;
  }

  // Does the encoding of this header start with "HTTP/", indicating that it
  // might be from a non-HTTP/2 server.
  bool IsProbableHttpResponse() const;

  // Produce strings useful for debugging/logging messages.
  std::string ToString() const;
  std::string FlagsToString() const;

  // 24 bit length of the payload after the header, including any padding.
  // First field in encoding.
  uint32_t payload_length;  // 24 bits

  // 31 bit stream id, with high bit (32nd bit) reserved (must be zero),
  // and is cleared during decoding.
  // Fourth field in encoding.
  uint32_t stream_id;

  // Type of the frame.
  // Second field in encoding.
  Http2FrameType type;

  // Flag bits, with interpretations that depend upon the frame type.
  // Flag bits not used by the frame type are cleared.
  // Third field in encoding.
  uint8_t flags;
};

QUICHE_EXPORT bool operator==(const Http2FrameHeader& a,
                              const Http2FrameHeader& b);
QUICHE_EXPORT inline bool operator!=(const Http2FrameHeader& a,
                                     const Http2FrameHeader& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2FrameHeader& v);

// Http2PriorityFields:

struct QUICHE_EXPORT Http2PriorityFields {
  Http2PriorityFields() {}
  Http2PriorityFields(uint32_t stream_dependency, uint32_t weight,
                      bool is_exclusive)
      : stream_dependency(stream_dependency),
        weight(weight),
        is_exclusive(is_exclusive) {
    // Can't have the high-bit set in the stream id because we need to use
    // that for the EXCLUSIVE flag bit.
    QUICHE_DCHECK_EQ(stream_dependency, stream_dependency & StreamIdMask())
        << "Stream Dependency is only a 31-bit field.\n"
        << ToString();
    QUICHE_DCHECK_LE(1u, weight) << "Weight is too small.";
    QUICHE_DCHECK_LE(weight, 256u) << "Weight is too large.";
  }
  static constexpr size_t EncodedSize() { return 5; }

  // Produce strings useful for debugging/logging messages.
  std::string ToString() const;

  // A 31-bit stream identifier for the stream that this stream depends on.
  uint32_t stream_dependency;

  // Weight (1 to 256) is encoded as a byte in the range 0 to 255, so we
  // add one when decoding, and store it in a field larger than a byte.
  uint32_t weight;

  // A single-bit flag indicating that the stream dependency is exclusive;
  // extracted from high bit of stream dependency field during decoding.
  bool is_exclusive;
};

QUICHE_EXPORT bool operator==(const Http2PriorityFields& a,
                              const Http2PriorityFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2PriorityFields& a,
                                     const Http2PriorityFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2PriorityFields& v);

// Http2RstStreamFields:

struct QUICHE_EXPORT Http2RstStreamFields {
  static constexpr size_t EncodedSize() { return 4; }
  bool IsSupportedErrorCode() const {
    return IsSupportedHttp2ErrorCode(error_code);
  }

  Http2ErrorCode error_code;
};

QUICHE_EXPORT bool operator==(const Http2RstStreamFields& a,
                              const Http2RstStreamFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2RstStreamFields& a,
                                     const Http2RstStreamFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2RstStreamFields& v);

// Http2SettingFields:

struct QUICHE_EXPORT Http2SettingFields {
  Http2SettingFields() {}
  Http2SettingFields(Http2SettingsParameter parameter, uint32_t value)
      : parameter(parameter), value(value) {}
  static constexpr size_t EncodedSize() { return 6; }
  bool IsSupportedParameter() const {
    return IsSupportedHttp2SettingsParameter(parameter);
  }

  Http2SettingsParameter parameter;
  uint32_t value;
};

QUICHE_EXPORT bool operator==(const Http2SettingFields& a,
                              const Http2SettingFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2SettingFields& a,
                                     const Http2SettingFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2SettingFields& v);

// Http2PushPromiseFields:

struct QUICHE_EXPORT Http2PushPromiseFields {
  static constexpr size_t EncodedSize() { return 4; }

  uint32_t promised_stream_id;
};

QUICHE_EXPORT bool operator==(const Http2PushPromiseFields& a,
                              const Http2PushPromiseFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2PushPromiseFields& a,
                                     const Http2PushPromiseFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2PushPromiseFields& v);

// Http2PingFields:

struct QUICHE_EXPORT Http2PingFields {
  static constexpr size_t EncodedSize() { return 8; }

  uint8_t opaque_bytes[8];
};

QUICHE_EXPORT bool operator==(const Http2PingFields& a,
                              const Http2PingFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2PingFields& a,
                                     const Http2PingFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2PingFields& v);

// Http2GoAwayFields:

struct QUICHE_EXPORT Http2GoAwayFields {
  Http2GoAwayFields() {}
  Http2GoAwayFields(uint32_t last_stream_id, Http2ErrorCode error_code)
      : last_stream_id(last_stream_id), error_code(error_code) {}
  static constexpr size_t EncodedSize() { return 8; }
  bool IsSupportedErrorCode() const {
    return IsSupportedHttp2ErrorCode(error_code);
  }

  uint32_t last_stream_id;
  Http2ErrorCode error_code;
};

QUICHE_EXPORT bool operator==(const Http2GoAwayFields& a,
                              const Http2GoAwayFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2GoAwayFields& a,
                                     const Http2GoAwayFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2GoAwayFields& v);

// Http2WindowUpdateFields:

struct QUICHE_EXPORT Http2WindowUpdateFields {
  static constexpr size_t EncodedSize() { return 4; }

  // 31-bit, unsigned increase in the window size (only positive values are
  // allowed). The high-bit is reserved for the future.
  uint32_t window_size_increment;
};

QUICHE_EXPORT bool operator==(const Http2WindowUpdateFields& a,
                              const Http2WindowUpdateFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2WindowUpdateFields& a,
                                     const Http2WindowUpdateFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2WindowUpdateFields& v);

// Http2AltSvcFields:

struct QUICHE_EXPORT Http2AltSvcFields {
  static constexpr size_t EncodedSize() { return 2; }

  // This is the one fixed size portion of the ALTSVC payload.
  uint16_t origin_length;
};

QUICHE_EXPORT bool operator==(const Http2AltSvcFields& a,
                              const Http2AltSvcFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2AltSvcFields& a,
                                     const Http2AltSvcFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2AltSvcFields& v);

// Http2PriorityUpdateFields:

struct QUICHE_EXPORT Http2PriorityUpdateFields {
  Http2PriorityUpdateFields() {}
  Http2PriorityUpdateFields(uint32_t prioritized_stream_id)
      : prioritized_stream_id(prioritized_stream_id) {}
  static constexpr size_t EncodedSize() { return 4; }

  // Produce strings useful for debugging/logging messages.
  std::string ToString() const;

  // The 31-bit stream identifier of the stream whose priority is updated.
  uint32_t prioritized_stream_id;
};

QUICHE_EXPORT bool operator==(const Http2PriorityUpdateFields& a,
                              const Http2PriorityUpdateFields& b);
QUICHE_EXPORT inline bool operator!=(const Http2PriorityUpdateFields& a,
                                     const Http2PriorityUpdateFields& b) {
  return !(a == b);
}
QUICHE_EXPORT std::ostream& operator<<(std::ostream& out,
                                       const Http2PriorityUpdateFields& v);

}  // namespace http2

#endif  // QUICHE_HTTP2_HTTP2_STRUCTURES_H_
