#ifndef SRC_NODE_HTTP2_H_
#define SRC_NODE_HTTP2_H_

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

// clang-format off
#include "node.h"  // nghttp2.h needs ssize_t
// clang-format on
#include "nghttp2/nghttp2.h"

#include "env.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++);
    ClearHeaders();
  }

  void ClearHeaders() {
    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);

  void DecrefHeaders(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_;
  std::unique_ptr<v8::BackingStore> 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 static_cast<const nghttp2_origin_entry*>(bs_->Data());
  }

  size_t length() const {
    return count_;
  }

 private:
  size_t count_;
  std::unique_ptr<v8::BackingStore> bs_;
};

#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_
