#ifndef SRC_NODE_HTTP2_H_
#define SRC_NODE_HTTP2_H_

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

// FIXME(joyeecheung): nghttp2.h needs stdint.h to compile on Windows
#include <cstdint>
#include "nghttp2/nghttp2.h"

#include "env.h"
#include "allocated_buffer.h"
#include "aliased_struct.h"
#include "node_http2_state.h"
#include "node_http_common.h"
#include "node_mem.h"
#include "node_perf.h"
#include "stream_base.h"
#include "string_bytes.h"

#include <algorithm>
#include <queue>

namespace node {
namespace http2 {

// Constants in all caps are exported as user-facing constants
// in JavaScript. Constants using the kName pattern are internal
// only.

// We strictly limit the number of outstanding unacknowledged PINGS a user
// may send in order to prevent abuse. The current default cap is 10. The
// user may set a different limit using a per Http2Session configuration
// option.
constexpr size_t kDefaultMaxPings = 10;

// Also strictly limit the number of outstanding SETTINGS frames a user sends
constexpr size_t kDefaultMaxSettings = 10;

// Default maximum total memory cap for Http2Session.
constexpr uint64_t kDefaultMaxSessionMemory = 10000000;

// These are the standard HTTP/2 defaults as specified by the RFC
constexpr uint32_t DEFAULT_SETTINGS_HEADER_TABLE_SIZE = 4096;
constexpr uint32_t DEFAULT_SETTINGS_ENABLE_PUSH = 1;
constexpr uint32_t DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS = 0xffffffffu;
constexpr uint32_t DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE = 65535;
constexpr uint32_t DEFAULT_SETTINGS_MAX_FRAME_SIZE = 16384;
constexpr uint32_t DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE = 65535;
constexpr uint32_t DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0;
constexpr uint32_t MAX_MAX_FRAME_SIZE = 16777215;
constexpr uint32_t MIN_MAX_FRAME_SIZE = DEFAULT_SETTINGS_MAX_FRAME_SIZE;
constexpr uint32_t MAX_INITIAL_WINDOW_SIZE = 2147483647;

// Stream is not going to have any DATA frames
constexpr int STREAM_OPTION_EMPTY_PAYLOAD = 0x1;

// Stream might have trailing headers
constexpr int STREAM_OPTION_GET_TRAILERS = 0x2;

// Http2Stream internal states
constexpr int kStreamStateNone = 0x0;
constexpr int kStreamStateShut = 0x1;
constexpr int kStreamStateReadStart = 0x2;
constexpr int kStreamStateReadPaused = 0x4;
constexpr int kStreamStateClosed = 0x8;
constexpr int kStreamStateDestroyed = 0x10;
constexpr int kStreamStateTrailers = 0x20;

// Http2Session internal states
constexpr int kSessionStateNone = 0x0;
constexpr int kSessionStateHasScope = 0x1;
constexpr int kSessionStateWriteScheduled = 0x2;
constexpr int kSessionStateClosed = 0x4;
constexpr int kSessionStateClosing = 0x8;
constexpr int kSessionStateSending = 0x10;
constexpr int kSessionStateWriteInProgress = 0x20;
constexpr int kSessionStateReadingStopped = 0x40;
constexpr int kSessionStateReceivePaused = 0x80;

// The Padding Strategy determines the method by which extra padding is
// selected for HEADERS and DATA frames. These are configurable via the
// options passed in to a Http2Session object.
enum PaddingStrategy {
  // No padding strategy. This is the default.
  PADDING_STRATEGY_NONE,
  // Attempts to ensure that the frame is 8-byte aligned
  PADDING_STRATEGY_ALIGNED,
  // Padding will ensure all data frames are maxFrameSize
  PADDING_STRATEGY_MAX,
  // Removed and turned into an alias because it is unreasonably expensive for
  // very little benefit.
  PADDING_STRATEGY_CALLBACK = PADDING_STRATEGY_ALIGNED
};

enum SessionType {
  NGHTTP2_SESSION_SERVER,
  NGHTTP2_SESSION_CLIENT
};

template <typename T, void(*fn)(T*)>
struct Nghttp2Deleter {
  void operator()(T* ptr) const noexcept { fn(ptr); }
};

using Nghttp2OptionPointer =
    std::unique_ptr<nghttp2_option,
                    Nghttp2Deleter<nghttp2_option, nghttp2_option_del>>;

using Nghttp2SessionPointer =
    std::unique_ptr<nghttp2_session,
                    Nghttp2Deleter<nghttp2_session, nghttp2_session_del>>;

using Nghttp2SessionCallbacksPointer =
    std::unique_ptr<nghttp2_session_callbacks,
                    Nghttp2Deleter<nghttp2_session_callbacks,
                                   nghttp2_session_callbacks_del>>;

struct Http2HeadersTraits {
  typedef nghttp2_nv nv_t;
};

struct Http2RcBufferPointerTraits {
  typedef nghttp2_rcbuf rcbuf_t;
  typedef nghttp2_vec vector_t;

  static void inc(rcbuf_t* buf) {
    CHECK_NOT_NULL(buf);
    nghttp2_rcbuf_incref(buf);
  }
  static void dec(rcbuf_t* buf) {
    CHECK_NOT_NULL(buf);
    nghttp2_rcbuf_decref(buf);
  }
  static vector_t get_vec(rcbuf_t* buf) {
    CHECK_NOT_NULL(buf);
    return nghttp2_rcbuf_get_buf(buf);
  }
  static bool is_static(const rcbuf_t* buf) {
    CHECK_NOT_NULL(buf);
    return nghttp2_rcbuf_is_static(buf);
  }
};

using Http2Headers = NgHeaders<Http2HeadersTraits>;
using Http2RcBufferPointer = NgRcBufPointer<Http2RcBufferPointerTraits>;

struct NgHttp2StreamWrite : public MemoryRetainer {
  BaseObjectPtr<AsyncWrap> req_wrap;
  uv_buf_t buf;

  inline explicit NgHttp2StreamWrite(uv_buf_t buf_) : buf(buf_) {}
  inline NgHttp2StreamWrite(BaseObjectPtr<AsyncWrap> req_wrap, uv_buf_t buf_) :
      req_wrap(std::move(req_wrap)), buf(buf_) {}

  void MemoryInfo(MemoryTracker* tracker) const override;
  SET_MEMORY_INFO_NAME(NgHttp2StreamWrite)
  SET_SELF_SIZE(NgHttp2StreamWrite)
};

typedef uint32_t(*get_setting)(nghttp2_session* session,
                               nghttp2_settings_id id);

class Http2Ping;
class Http2Session;
class Http2Settings;
class Http2Stream;
class Origins;

// This scope should be present when any call into nghttp2 that may schedule
// data to be written to the underlying transport is made, and schedules
// such a write automatically once the scope is exited.
class Http2Scope {
 public:
  explicit Http2Scope(Http2Stream* stream);
  explicit Http2Scope(Http2Session* session);
  ~Http2Scope();

 private:
  BaseObjectPtr<Http2Session> session_;
};

// The Http2Options class is used to parse the options object passed in to
// a Http2Session object and convert those into an appropriate nghttp2_option
// struct. This is the primary mechanism by which the Http2Session object is
// configured.
class Http2Options {
 public:
  Http2Options(Http2State* http2_state,
               SessionType type);

  ~Http2Options() = default;

  nghttp2_option* operator*() const {
    return options_.get();
  }

  void set_max_header_pairs(uint32_t max) {
    max_header_pairs_ = max;
  }

  uint32_t max_header_pairs() const {
    return max_header_pairs_;
  }

  void set_padding_strategy(PaddingStrategy val) {
    padding_strategy_ = val;
  }

  PaddingStrategy padding_strategy() const {
    return padding_strategy_;
  }

  void set_max_outstanding_pings(size_t max) {
    max_outstanding_pings_ = max;
  }

  size_t max_outstanding_pings() const {
    return max_outstanding_pings_;
  }

  void set_max_outstanding_settings(size_t max) {
    max_outstanding_settings_ = max;
  }

  size_t max_outstanding_settings() const {
    return max_outstanding_settings_;
  }

  void set_max_session_memory(uint64_t max) {
    max_session_memory_ = max;
  }

  uint64_t max_session_memory() const {
    return max_session_memory_;
  }

 private:
  Nghttp2OptionPointer options_;
  uint64_t max_session_memory_ = kDefaultMaxSessionMemory;
  uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS;
  PaddingStrategy padding_strategy_ = PADDING_STRATEGY_NONE;
  size_t max_outstanding_pings_ = kDefaultMaxPings;
  size_t max_outstanding_settings_ = kDefaultMaxSettings;
};

struct Http2Priority : public nghttp2_priority_spec {
  Http2Priority(Environment* env,
                v8::Local<v8::Value> parent,
                v8::Local<v8::Value> weight,
                v8::Local<v8::Value> exclusive);
};

class Http2StreamListener : public StreamListener {
 public:
  uv_buf_t OnStreamAlloc(size_t suggested_size) override;
  void OnStreamRead(ssize_t nread, const uv_buf_t& buf) override;
};

struct Http2HeaderTraits {
  typedef Http2RcBufferPointer rcbufferpointer_t;
  typedef Http2Session allocator_t;

  // HTTP/2 does not support identifying header names by token id.
  // HTTP/3 will, however, so we prepare for that now.
  static const char* ToHttpHeaderName(int32_t token) { return nullptr; }
};

using Http2Header = NgHeader<Http2HeaderTraits>;

class Http2Stream : public AsyncWrap,
                    public StreamBase {
 public:
  static Http2Stream* New(
      Http2Session* session,
      int32_t id,
      nghttp2_headers_category category = NGHTTP2_HCAT_HEADERS,
      int options = 0);
  ~Http2Stream() override;

  nghttp2_stream* operator*() const;

  nghttp2_stream* stream() const;

  Http2Session* session() { return session_.get(); }
  const Http2Session* session() const { return session_.get(); }

  // Required for StreamBase
  int ReadStart() override;

  // Required for StreamBase
  int ReadStop() override;

  // Required for StreamBase
  ShutdownWrap* CreateShutdownWrap(v8::Local<v8::Object> object) override;
  int DoShutdown(ShutdownWrap* req_wrap) override;

  bool HasWantsWrite() const override { return true; }

  // Initiate a response on this stream.
  int SubmitResponse(const Http2Headers& headers, int options);

  // Submit informational headers for this stream
  int SubmitInfo(const Http2Headers& headers);

  // Submit trailing headers for this stream
  int SubmitTrailers(const Http2Headers& headers);
  void OnTrailers();

  // Submit a PRIORITY frame for this stream
  int SubmitPriority(const Http2Priority& priority, bool silent = false);

  // Submits an RST_STREAM frame using the given code
  void SubmitRstStream(const uint32_t code);

  void FlushRstStream();

  // Submits a PUSH_PROMISE frame with this stream as the parent.
  Http2Stream* SubmitPushPromise(
      const Http2Headers& headers,
      int32_t* ret,
      int options = 0);


  void Close(int32_t code);

  // Destroy this stream instance and free all held memory.
  void Destroy();

  bool is_destroyed() const {
    return flags_ & kStreamStateDestroyed;
  }

  bool is_writable() const {
    return !(flags_ & kStreamStateShut);
  }

  bool is_paused() const {
    return flags_ & kStreamStateReadPaused;
  }

  bool is_closed() const {
    return flags_ & kStreamStateClosed;
  }

  bool has_trailers() const {
    return flags_ & kStreamStateTrailers;
  }

  void set_has_trailers(bool on = true) {
    if (on)
      flags_ |= kStreamStateTrailers;
    else
      flags_ &= ~kStreamStateTrailers;
  }

  void set_closed() {
    flags_ |= kStreamStateClosed;
  }

  void set_destroyed() {
    flags_ |= kStreamStateDestroyed;
  }

  void set_not_writable() {
    flags_ |= kStreamStateShut;
  }

  void set_reading(bool on = true) {
    if (on) {
      flags_ |= kStreamStateReadStart;
      set_paused(false);
    } else {}
  }

  void set_paused(bool on = true) {
    if (on)
      flags_ |= kStreamStateReadPaused;
    else
      flags_ &= ~kStreamStateReadPaused;
  }

  // Returns true if this stream is in the reading state, which occurs when
  // the kStreamStateReadStart flag has been set and the
  // kStreamStateReadPaused flag is *not* set.
  bool is_reading() const {
    return flags_ & kStreamStateReadStart && !is_paused();
  }

  // Returns the RST_STREAM code used to close this stream
  int32_t code() const { return code_; }

  // Returns the stream identifier for this stream
  int32_t id() const { return id_; }

  void IncrementAvailableOutboundLength(size_t amount);
  void DecrementAvailableOutboundLength(size_t amount);

  bool AddHeader(nghttp2_rcbuf* name, nghttp2_rcbuf* value, uint8_t flags);

  template <typename Fn>
  void TransferHeaders(Fn&& fn) {
    size_t i = 0;
    for (const auto& header : current_headers_ )
      fn(header, i++);
    current_headers_.clear();
  }

  size_t headers_count() const {
    return current_headers_.size();
  }

  nghttp2_headers_category headers_category() const {
    return current_headers_category_;
  }

  void StartHeaders(nghttp2_headers_category category);

  // Required for StreamBase
  bool IsAlive() override {
    return true;
  }

  // Required for StreamBase
  bool IsClosing() override {
    return false;
  }

  AsyncWrap* GetAsyncWrap() override { return this; }

  int DoWrite(WriteWrap* w, uv_buf_t* bufs, size_t count,
              uv_stream_t* send_handle) override;

  void MemoryInfo(MemoryTracker* tracker) const override;
  SET_MEMORY_INFO_NAME(Http2Stream)
  SET_SELF_SIZE(Http2Stream)

  std::string diagnostic_name() const override;

  // JavaScript API
  static void GetID(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Destroy(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Priority(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void PushPromise(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void RefreshState(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Info(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Trailers(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Respond(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void RstStream(const v8::FunctionCallbackInfo<v8::Value>& args);

  class Provider;

  struct Statistics {
    uint64_t start_time;
    uint64_t end_time;
    uint64_t first_header;     // Time first header was received
    uint64_t first_byte;       // Time first DATA frame byte was received
    uint64_t first_byte_sent;  // Time first DATA frame byte was sent
    uint64_t sent_bytes;
    uint64_t received_bytes;
    uint64_t id;
  };

  Statistics statistics_ = {};

 private:
  Http2Stream(Http2Session* session,
              v8::Local<v8::Object> obj,
              int32_t id,
              nghttp2_headers_category category,
              int options);

  void EmitStatistics();

  BaseObjectWeakPtr<Http2Session> session_;     // The Parent HTTP/2 Session
  int32_t id_ = 0;                              // The Stream Identifier
  int32_t code_ = NGHTTP2_NO_ERROR;             // The RST_STREAM code (if any)
  int flags_ = kStreamStateNone;        // Internal state flags

  uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS;
  uint32_t max_header_length_ = DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE;

  // The Current Headers block... As headers are received for this stream,
  // they are temporarily stored here until the OnFrameReceived is called
  // signalling the end of the HEADERS frame
  nghttp2_headers_category current_headers_category_ = NGHTTP2_HCAT_HEADERS;
  uint32_t current_headers_length_ = 0;  // total number of octets
  std::vector<Http2Header> current_headers_;

  // This keeps track of the amount of data read from the socket while the
  // socket was in paused mode. When `ReadStart()` is called (and not before
  // then), we tell nghttp2 that we consumed that data to get proper
  // backpressure handling.
  size_t inbound_consumed_data_while_paused_ = 0;

  // Outbound Data... This is the data written by the JS layer that is
  // waiting to be written out to the socket.
  std::queue<NgHttp2StreamWrite> queue_;
  size_t available_outbound_length_ = 0;

  Http2StreamListener stream_listener_;

  friend class Http2Session;
};

class Http2Stream::Provider {
 public:
  Provider(Http2Stream* stream, int options);
  explicit Provider(int options);
  virtual ~Provider();

  nghttp2_data_provider* operator*() {
    return !empty_ ? &provider_ : nullptr;
  }

  class FD;
  class Stream;
 protected:
  nghttp2_data_provider provider_;

 private:
  bool empty_ = false;
};

class Http2Stream::Provider::Stream : public Http2Stream::Provider {
 public:
  Stream(Http2Stream* stream, int options);
  explicit Stream(int options);

  static ssize_t OnRead(nghttp2_session* session,
                        int32_t id,
                        uint8_t* buf,
                        size_t length,
                        uint32_t* flags,
                        nghttp2_data_source* source,
                        void* user_data);
};

struct SessionJSFields {
  uint8_t bitfield;
  uint8_t priority_listener_count;
  uint8_t frame_error_listener_count;
  uint32_t max_invalid_frames = 1000;
  uint32_t max_rejected_streams = 100;
};

// Indices for js_fields_, which serves as a way to communicate data with JS
// land fast. In particular, we store information about the number/presence
// of certain event listeners in JS, and skip calls from C++ into JS if they
// are missing.
enum SessionUint8Fields {
  kBitfield = offsetof(SessionJSFields, bitfield),  // See below
  kSessionPriorityListenerCount =
      offsetof(SessionJSFields, priority_listener_count),
  kSessionFrameErrorListenerCount =
      offsetof(SessionJSFields, frame_error_listener_count),
  kSessionMaxInvalidFrames = offsetof(SessionJSFields, max_invalid_frames),
  kSessionMaxRejectedStreams = offsetof(SessionJSFields, max_rejected_streams),
  kSessionUint8FieldCount = sizeof(SessionJSFields)
};

enum SessionBitfieldFlags {
  kSessionHasRemoteSettingsListeners,
  kSessionRemoteSettingsIsUpToDate,
  kSessionHasPingListeners,
  kSessionHasAltsvcListeners
};

class Http2Session : public AsyncWrap,
                     public StreamListener,
                     public mem::NgLibMemoryManager<Http2Session, nghttp2_mem> {
 public:
  Http2Session(Http2State* http2_state,
               v8::Local<v8::Object> wrap,
               SessionType type = NGHTTP2_SESSION_SERVER);
  ~Http2Session() override;

  StreamBase* underlying_stream() {
    return static_cast<StreamBase*>(stream_);
  }

  void Close(uint32_t code = NGHTTP2_NO_ERROR,
             bool socket_closed = false);

  void Consume(v8::Local<v8::Object> stream);

  void Goaway(uint32_t code, int32_t lastStreamID,
              const uint8_t* data, size_t len);

  void AltSvc(int32_t id,
              uint8_t* origin,
              size_t origin_len,
              uint8_t* value,
              size_t value_len);

  void Origin(const Origins& origins);

  uint8_t SendPendingData();

  // Submits a new request. If the request is a success, assigned
  // will be a pointer to the Http2Stream instance assigned.
  // This only works if the session is a client session.
  Http2Stream* SubmitRequest(
      const Http2Priority& priority,
      const Http2Headers& headers,
      int32_t* ret,
      int options = 0);

  SessionType type() const { return session_type_; }

  nghttp2_session* session() const { return session_.get(); }

  nghttp2_session* operator*() { return session_.get(); }

  uint32_t max_header_pairs() const { return max_header_pairs_; }

  const char* TypeName() const;

  bool is_destroyed() {
    return (flags_ & kSessionStateClosed) || session_ == nullptr;
  }

  void set_destroyed() {
    flags_ |= kSessionStateClosed;
  }

#define IS_FLAG(name, flag)                                                    \
  bool is_##name() const { return flags_ & flag; }                             \
  void set_##name(bool on = true) {                                            \
    if (on)                                                                    \
      flags_ |= flag;                                                          \
    else                                                                       \
      flags_ &= ~flag;                                                         \
  }

  IS_FLAG(in_scope, kSessionStateHasScope)
  IS_FLAG(write_scheduled, kSessionStateWriteScheduled)
  IS_FLAG(closing, kSessionStateClosing)
  IS_FLAG(sending, kSessionStateSending)
  IS_FLAG(write_in_progress, kSessionStateWriteInProgress)
  IS_FLAG(reading_stopped, kSessionStateReadingStopped)
  IS_FLAG(receive_paused, kSessionStateReceivePaused)

#undef IS_FLAG

  // Schedule a write if nghttp2 indicates it wants to write to the socket.
  void MaybeScheduleWrite();

  // Stop reading if nghttp2 doesn't want to anymore.
  void MaybeStopReading();

  // Returns pointer to the stream, or nullptr if stream does not exist
  BaseObjectPtr<Http2Stream> FindStream(int32_t id);

  bool CanAddStream();

  // Adds a stream instance to this session
  void AddStream(Http2Stream* stream);

  // Removes a stream instance from this session
  BaseObjectPtr<Http2Stream> RemoveStream(int32_t id);

  // Indicates whether there currently exist outgoing buffers for this stream.
  bool HasWritesOnSocketForStream(Http2Stream* stream);

  // Write data from stream_buf_ to the session.
  // This will call the error callback if an error occurs.
  void ConsumeHTTP2Data();

  void MemoryInfo(MemoryTracker* tracker) const override;
  SET_MEMORY_INFO_NAME(Http2Session)
  SET_SELF_SIZE(Http2Session)

  std::string diagnostic_name() const override;

  // Schedule an RstStream for after the current write finishes.
  void AddPendingRstStream(int32_t stream_id) {
    pending_rst_streams_.emplace_back(stream_id);
  }

  bool has_pending_rststream(int32_t stream_id) {
    return pending_rst_streams_.end() !=
        std::find(pending_rst_streams_.begin(),
            pending_rst_streams_.end(),
            stream_id);
  }

  // Handle reads/writes from the underlying network transport.
  uv_buf_t OnStreamAlloc(size_t suggested_size) override;
  void OnStreamRead(ssize_t nread, const uv_buf_t& buf) override;
  void OnStreamAfterWrite(WriteWrap* w, int status) override;

  // Implementation for mem::NgLibMemoryManager
  void CheckAllocatedSize(size_t previous_size) const;
  void IncreaseAllocatedSize(size_t size);
  void DecreaseAllocatedSize(size_t size);

  // The JavaScript API
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Consume(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Receive(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Destroy(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Settings(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Request(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void SetNextStreamID(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void SetLocalWindowSize(
      const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Goaway(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void UpdateChunksSent(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void RefreshState(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Ping(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void AltSvc(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void Origin(const v8::FunctionCallbackInfo<v8::Value>& args);

  template <get_setting fn>
  static void RefreshSettings(const v8::FunctionCallbackInfo<v8::Value>& args);

  uv_loop_t* event_loop() const {
    return env()->event_loop();
  }

  Http2State* http2_state() const { return http2_state_.get(); }

  BaseObjectPtr<Http2Ping> PopPing();
  bool AddPing(const uint8_t* data, v8::Local<v8::Function> callback);

  BaseObjectPtr<Http2Settings> PopSettings();
  bool AddSettings(v8::Local<v8::Function> callback);

  void IncrementCurrentSessionMemory(uint64_t amount) {
    current_session_memory_ += amount;
  }

  void DecrementCurrentSessionMemory(uint64_t amount) {
    DCHECK_LE(amount, current_session_memory_);
    current_session_memory_ -= amount;
  }

  // Tell our custom memory allocator that this rcbuf is independent of
  // this session now, and may outlive it.
  void StopTrackingRcbuf(nghttp2_rcbuf* buf);

  // Returns the current session memory including memory allocated by nghttp2,
  // the current outbound storage queue, and pending writes.
  uint64_t current_session_memory() const {
    uint64_t total = current_session_memory_ + sizeof(Http2Session);
    total += current_nghttp2_memory_;
    total += outgoing_storage_.size();
    return total;
  }

  // Return true if current_session_memory + amount is less than the max
  bool has_available_session_memory(uint64_t amount) const {
    return current_session_memory() + amount <= max_session_memory_;
  }

  struct Statistics {
    uint64_t start_time;
    uint64_t end_time;
    uint64_t ping_rtt;
    uint64_t data_sent;
    uint64_t data_received;
    uint32_t frame_count;
    uint32_t frame_sent;
    int32_t stream_count;
    size_t max_concurrent_streams;
    double stream_average_duration;
    SessionType session_type;
  };

  Statistics statistics_ = {};

 private:
  void EmitStatistics();

  // Frame Padding Strategies
  ssize_t OnDWordAlignedPadding(size_t frameLength,
                                size_t maxPayloadLen);
  ssize_t OnMaxFrameSizePadding(size_t frameLength,
                                size_t maxPayloadLen);

  // Frame Handler
  int HandleDataFrame(const nghttp2_frame* frame);
  void HandleGoawayFrame(const nghttp2_frame* frame);
  void HandleHeadersFrame(const nghttp2_frame* frame);
  void HandlePriorityFrame(const nghttp2_frame* frame);
  void HandleSettingsFrame(const nghttp2_frame* frame);
  void HandlePingFrame(const nghttp2_frame* frame);
  void HandleAltSvcFrame(const nghttp2_frame* frame);
  void HandleOriginFrame(const nghttp2_frame* frame);

  // nghttp2 callbacks
  static int OnBeginHeadersCallback(
      nghttp2_session* session,
      const nghttp2_frame* frame,
      void* user_data);
  static int OnHeaderCallback(
      nghttp2_session* session,
      const nghttp2_frame* frame,
      nghttp2_rcbuf* name,
      nghttp2_rcbuf* value,
      uint8_t flags,
      void* user_data);
  static int OnFrameReceive(
      nghttp2_session* session,
      const nghttp2_frame* frame,
      void* user_data);
  static int OnFrameNotSent(
      nghttp2_session* session,
      const nghttp2_frame* frame,
      int error_code,
      void* user_data);
  static int OnFrameSent(
      nghttp2_session* session,
      const nghttp2_frame* frame,
      void* user_data);
  static int OnStreamClose(
      nghttp2_session* session,
      int32_t id,
      uint32_t code,
      void* user_data);
  static int OnInvalidHeader(
      nghttp2_session* session,
      const nghttp2_frame* frame,
      nghttp2_rcbuf* name,
      nghttp2_rcbuf* value,
      uint8_t flags,
      void* user_data);
  static int OnDataChunkReceived(
      nghttp2_session* session,
      uint8_t flags,
      int32_t id,
      const uint8_t* data,
      size_t len,
      void* user_data);
  static ssize_t OnSelectPadding(
      nghttp2_session* session,
      const nghttp2_frame* frame,
      size_t maxPayloadLen,
      void* user_data);
  static int OnNghttpError(
      nghttp2_session* session,
      const char* message,
      size_t len,
      void* user_data);
  static int OnSendData(
      nghttp2_session* session,
      nghttp2_frame* frame,
      const uint8_t* framehd,
      size_t length,
      nghttp2_data_source* source,
      void* user_data);
  static int OnInvalidFrame(
      nghttp2_session* session,
      const nghttp2_frame* frame,
      int lib_error_code,
      void* user_data);

  struct Callbacks {
    explicit Callbacks(bool kHasGetPaddingCallback);

    Nghttp2SessionCallbacksPointer callbacks;
  };

  /* Use callback_struct_saved[kHasGetPaddingCallback ? 1 : 0] */
  static const Callbacks callback_struct_saved[2];

  // The underlying nghttp2_session handle
  Nghttp2SessionPointer session_;

  // JS-accessible numeric fields, as indexed by SessionUint8Fields.
  AliasedStruct<SessionJSFields> js_fields_;

  // The session type: client or server
  SessionType session_type_;

  // The maximum number of header pairs permitted for streams on this session
  uint32_t max_header_pairs_ = DEFAULT_MAX_HEADER_LIST_PAIRS;

  // The maximum amount of memory allocated for this session
  uint64_t max_session_memory_ = kDefaultMaxSessionMemory;
  uint64_t current_session_memory_ = 0;
  // The amount of memory allocated by nghttp2 internals
  uint64_t current_nghttp2_memory_ = 0;

  // The collection of active Http2Streams associated with this session
  std::unordered_map<int32_t, BaseObjectPtr<Http2Stream>> streams_;

  int flags_ = kSessionStateNone;

  // The StreamBase instance being used for i/o
  PaddingStrategy padding_strategy_ = PADDING_STRATEGY_NONE;

  // use this to allow timeout tracking during long-lasting writes
  uint32_t chunks_sent_since_last_write_ = 0;

  uv_buf_t stream_buf_ = uv_buf_init(nullptr, 0);
  // When processing input data, either stream_buf_ab_ or stream_buf_allocation_
  // will be set. stream_buf_ab_ is lazily created from stream_buf_allocation_.
  v8::Global<v8::ArrayBuffer> stream_buf_ab_;
  AllocatedBuffer stream_buf_allocation_;
  size_t stream_buf_offset_ = 0;
  // Custom error code for errors that originated inside one of the callbacks
  // called by nghttp2_session_mem_recv.
  const char* custom_recv_error_code_ = nullptr;

  size_t max_outstanding_pings_ = kDefaultMaxPings;
  std::queue<BaseObjectPtr<Http2Ping>> outstanding_pings_;

  size_t max_outstanding_settings_ = kDefaultMaxSettings;
  std::queue<BaseObjectPtr<Http2Settings>> outstanding_settings_;

  std::vector<NgHttp2StreamWrite> outgoing_buffers_;
  std::vector<uint8_t> outgoing_storage_;
  size_t outgoing_length_ = 0;
  std::vector<int32_t> pending_rst_streams_;
  // Count streams that have been rejected while being opened. Exceeding a fixed
  // limit will result in the session being destroyed, as an indication of a
  // misbehaving peer. This counter is reset once new streams are being
  // accepted again.
  uint32_t rejected_stream_count_ = 0;
  // Also use the invalid frame count as a measure for rejecting input frames.
  uint32_t invalid_frame_count_ = 0;

  void PushOutgoingBuffer(NgHttp2StreamWrite&& write);

  BaseObjectPtr<Http2State> http2_state_;

  void CopyDataIntoOutgoing(const uint8_t* src, size_t src_length);
  void ClearOutgoing(int status);

  friend class Http2Scope;
  friend class Http2StreamListener;
};

struct Http2SessionPerformanceEntryTraits {
  static constexpr performance::PerformanceEntryType kType =
      performance::NODE_PERFORMANCE_ENTRY_TYPE_HTTP2;

  using Details = Http2Session::Statistics;

  static v8::MaybeLocal<v8::Object> GetDetails(
      Environment* env,
      const performance::PerformanceEntry<Http2SessionPerformanceEntryTraits>&
          entry);
};

struct Http2StreamPerformanceEntryTraits {
  static constexpr performance::PerformanceEntryType kType =
      performance::NODE_PERFORMANCE_ENTRY_TYPE_HTTP2;

  using Details = Http2Stream::Statistics;

  static v8::MaybeLocal<v8::Object> GetDetails(
      Environment* env,
      const performance::PerformanceEntry<Http2StreamPerformanceEntryTraits>&
          entry);
};

using Http2SessionPerformanceEntry =
    performance::PerformanceEntry<Http2SessionPerformanceEntryTraits>;
using Http2StreamPerformanceEntry =
    performance::PerformanceEntry<Http2StreamPerformanceEntryTraits>;

class Http2Ping : public AsyncWrap {
 public:
  explicit Http2Ping(
      Http2Session* session,
      v8::Local<v8::Object> obj,
      v8::Local<v8::Function> callback);

  void MemoryInfo(MemoryTracker* tracker) const override;
  SET_MEMORY_INFO_NAME(Http2Ping)
  SET_SELF_SIZE(Http2Ping)

  void Send(const uint8_t* payload);
  void Done(bool ack, const uint8_t* payload = nullptr);
  void DetachFromSession();

  v8::Local<v8::Function> callback() const;

 private:
  BaseObjectWeakPtr<Http2Session> session_;
  v8::Global<v8::Function> callback_;
  uint64_t startTime_;
};

// The Http2Settings class is used to parse the settings passed in for
// an Http2Session, converting those into an array of nghttp2_settings_entry
// structs.
class Http2Settings : public AsyncWrap {
 public:
  Http2Settings(Http2Session* session,
                v8::Local<v8::Object> obj,
                v8::Local<v8::Function> callback,
                uint64_t start_time = uv_hrtime());

  void MemoryInfo(MemoryTracker* tracker) const override;
  SET_MEMORY_INFO_NAME(Http2Settings)
  SET_SELF_SIZE(Http2Settings)

  void Send();
  void Done(bool ack);

  v8::Local<v8::Function> callback() const;

  // Returns a Buffer instance with the serialized SETTINGS payload
  v8::Local<v8::Value> Pack();

  static v8::Local<v8::Value> Pack(Http2State* state);

  // Resets the default values in the settings buffer
  static void RefreshDefaults(Http2State* http2_state);

  // Update the local or remote settings for the given session
  static void Update(Http2Session* session,
                     get_setting fn);

 private:
  static size_t Init(
      Http2State* http2_state,
      nghttp2_settings_entry* entries);

  static v8::Local<v8::Value> Pack(
      Environment* env,
      size_t count,
      const nghttp2_settings_entry* entries);

  BaseObjectWeakPtr<Http2Session> session_;
  v8::Global<v8::Function> callback_;
  uint64_t startTime_;
  size_t count_ = 0;
  nghttp2_settings_entry entries_[IDX_SETTINGS_COUNT];
};

class Origins {
 public:
  Origins(Environment* env,
          v8::Local<v8::String> origin_string,
          size_t origin_count);
  ~Origins() = default;

  const nghttp2_origin_entry* operator*() const {
    return reinterpret_cast<const nghttp2_origin_entry*>(buf_.data());
  }

  size_t length() const {
    return count_;
  }

 private:
  size_t count_;
  AllocatedBuffer buf_;
};

#define HTTP2_HIDDEN_CONSTANTS(V)                                              \
  V(NGHTTP2_HCAT_REQUEST)                                                      \
  V(NGHTTP2_HCAT_RESPONSE)                                                     \
  V(NGHTTP2_HCAT_PUSH_RESPONSE)                                                \
  V(NGHTTP2_HCAT_HEADERS)                                                      \
  V(NGHTTP2_NV_FLAG_NONE)                                                      \
  V(NGHTTP2_NV_FLAG_NO_INDEX)                                                  \
  V(NGHTTP2_ERR_DEFERRED)                                                      \
  V(NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE)                                       \
  V(NGHTTP2_ERR_INVALID_ARGUMENT)                                              \
  V(NGHTTP2_ERR_STREAM_CLOSED)                                                 \
  V(NGHTTP2_ERR_NOMEM)                                                         \
  V(STREAM_OPTION_EMPTY_PAYLOAD)                                               \
  V(STREAM_OPTION_GET_TRAILERS)

#define HTTP2_ERROR_CODES(V)                                                   \
  V(NGHTTP2_NO_ERROR)                                                          \
  V(NGHTTP2_PROTOCOL_ERROR)                                                    \
  V(NGHTTP2_INTERNAL_ERROR)                                                    \
  V(NGHTTP2_FLOW_CONTROL_ERROR)                                                \
  V(NGHTTP2_SETTINGS_TIMEOUT)                                                  \
  V(NGHTTP2_STREAM_CLOSED)                                                     \
  V(NGHTTP2_FRAME_SIZE_ERROR)                                                  \
  V(NGHTTP2_REFUSED_STREAM)                                                    \
  V(NGHTTP2_CANCEL)                                                            \
  V(NGHTTP2_COMPRESSION_ERROR)                                                 \
  V(NGHTTP2_CONNECT_ERROR)                                                     \
  V(NGHTTP2_ENHANCE_YOUR_CALM)                                                 \
  V(NGHTTP2_INADEQUATE_SECURITY)                                               \
  V(NGHTTP2_HTTP_1_1_REQUIRED)                                                 \

#define HTTP2_CONSTANTS(V)                                                     \
  V(NGHTTP2_ERR_FRAME_SIZE_ERROR)                                              \
  V(NGHTTP2_SESSION_SERVER)                                                    \
  V(NGHTTP2_SESSION_CLIENT)                                                    \
  V(NGHTTP2_STREAM_STATE_IDLE)                                                 \
  V(NGHTTP2_STREAM_STATE_OPEN)                                                 \
  V(NGHTTP2_STREAM_STATE_RESERVED_LOCAL)                                       \
  V(NGHTTP2_STREAM_STATE_RESERVED_REMOTE)                                      \
  V(NGHTTP2_STREAM_STATE_HALF_CLOSED_LOCAL)                                    \
  V(NGHTTP2_STREAM_STATE_HALF_CLOSED_REMOTE)                                   \
  V(NGHTTP2_STREAM_STATE_CLOSED)                                               \
  V(NGHTTP2_FLAG_NONE)                                                         \
  V(NGHTTP2_FLAG_END_STREAM)                                                   \
  V(NGHTTP2_FLAG_END_HEADERS)                                                  \
  V(NGHTTP2_FLAG_ACK)                                                          \
  V(NGHTTP2_FLAG_PADDED)                                                       \
  V(NGHTTP2_FLAG_PRIORITY)                                                     \
  V(DEFAULT_SETTINGS_HEADER_TABLE_SIZE)                                        \
  V(DEFAULT_SETTINGS_ENABLE_PUSH)                                              \
  V(DEFAULT_SETTINGS_MAX_CONCURRENT_STREAMS)                                   \
  V(DEFAULT_SETTINGS_INITIAL_WINDOW_SIZE)                                      \
  V(DEFAULT_SETTINGS_MAX_FRAME_SIZE)                                           \
  V(DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE)                                     \
  V(DEFAULT_SETTINGS_ENABLE_CONNECT_PROTOCOL)                                  \
  V(MAX_MAX_FRAME_SIZE)                                                        \
  V(MIN_MAX_FRAME_SIZE)                                                        \
  V(MAX_INITIAL_WINDOW_SIZE)                                                   \
  V(NGHTTP2_SETTINGS_HEADER_TABLE_SIZE)                                        \
  V(NGHTTP2_SETTINGS_ENABLE_PUSH)                                              \
  V(NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS)                                   \
  V(NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE)                                      \
  V(NGHTTP2_SETTINGS_MAX_FRAME_SIZE)                                           \
  V(NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE)                                     \
  V(NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL)                                  \
  V(PADDING_STRATEGY_NONE)                                                     \
  V(PADDING_STRATEGY_ALIGNED)                                                  \
  V(PADDING_STRATEGY_MAX)                                                      \
  V(PADDING_STRATEGY_CALLBACK)                                                 \
  HTTP2_ERROR_CODES(V)

#define HTTP2_SETTINGS(V)                                                      \
  V(HEADER_TABLE_SIZE)                                                         \
  V(ENABLE_PUSH)                                                               \
  V(MAX_CONCURRENT_STREAMS)                                                    \
  V(INITIAL_WINDOW_SIZE)                                                       \
  V(MAX_FRAME_SIZE)                                                            \
  V(MAX_HEADER_LIST_SIZE)                                                      \
  V(ENABLE_CONNECT_PROTOCOL)                                                   \

}  // namespace http2
}  // namespace node

#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#endif  // SRC_NODE_HTTP2_H_
