// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "memory_tracker-inl.h"
#include "node.h"
#include "node_buffer.h"

#include "async_wrap-inl.h"
#include "env-inl.h"
#include "threadpoolwork-inl.h"
#include "util-inl.h"

#include "v8.h"

#include "brotli/encode.h"
#include "brotli/decode.h"
#include "zlib.h"

#include <sys/types.h>

#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <atomic>

namespace node {

using v8::ArrayBuffer;
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Global;
using v8::HandleScope;
using v8::Int32;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Uint32Array;
using v8::Value;

namespace {

// Fewer than 64 bytes per chunk is not recommended.
// Technically it could work with as few as 8, but even 64 bytes
// is low.  Usually a MB or more is best.
#define Z_MIN_CHUNK 64
#define Z_MAX_CHUNK std::numeric_limits<double>::infinity()
#define Z_DEFAULT_CHUNK (16 * 1024)
#define Z_MIN_MEMLEVEL 1
#define Z_MAX_MEMLEVEL 9
#define Z_DEFAULT_MEMLEVEL 8
#define Z_MIN_LEVEL -1
#define Z_MAX_LEVEL 9
#define Z_DEFAULT_LEVEL Z_DEFAULT_COMPRESSION

#define ZLIB_ERROR_CODES(V)      \
  V(Z_OK)                        \
  V(Z_STREAM_END)                \
  V(Z_NEED_DICT)                 \
  V(Z_ERRNO)                     \
  V(Z_STREAM_ERROR)              \
  V(Z_DATA_ERROR)                \
  V(Z_MEM_ERROR)                 \
  V(Z_BUF_ERROR)                 \
  V(Z_VERSION_ERROR)             \

inline const char* ZlibStrerror(int err) {
#define V(code) if (err == code) return #code;
  ZLIB_ERROR_CODES(V)
#undef V
  return "Z_UNKNOWN_ERROR";
}

enum node_zlib_mode {
  NONE,
  DEFLATE,
  INFLATE,
  GZIP,
  GUNZIP,
  DEFLATERAW,
  INFLATERAW,
  UNZIP,
  BROTLI_DECODE,
  BROTLI_ENCODE
};

#define GZIP_HEADER_ID1 0x1f
#define GZIP_HEADER_ID2 0x8b

struct CompressionError {
  CompressionError(const char* message, const char* code, int err)
      : message(message),
        code(code),
        err(err) {
    CHECK_NOT_NULL(message);
  }

  CompressionError() = default;

  const char* message = nullptr;
  const char* code = nullptr;
  int err = 0;

  inline bool IsError() const { return code != nullptr; }
};

class ZlibContext : public MemoryRetainer {
 public:
  ZlibContext() = default;

  // Streaming-related, should be available for all compression libraries:
  void Close();
  void DoThreadPoolWork();
  void SetBuffers(char* in, uint32_t in_len, char* out, uint32_t out_len);
  void SetFlush(int flush);
  void GetAfterWriteOffsets(uint32_t* avail_in, uint32_t* avail_out) const;
  CompressionError GetErrorInfo() const;
  inline void SetMode(node_zlib_mode mode) { mode_ = mode; }
  CompressionError ResetStream();

  // Zlib-specific:
  void Init(int level, int window_bits, int mem_level, int strategy,
            std::vector<unsigned char>&& dictionary);
  void SetAllocationFunctions(alloc_func alloc, free_func free, void* opaque);
  CompressionError SetParams(int level, int strategy);

  SET_MEMORY_INFO_NAME(ZlibContext)
  SET_SELF_SIZE(ZlibContext)

  void MemoryInfo(MemoryTracker* tracker) const override {
    tracker->TrackField("dictionary", dictionary_);
  }

  ZlibContext(const ZlibContext&) = delete;
  ZlibContext& operator=(const ZlibContext&) = delete;

 private:
  CompressionError ErrorForMessage(const char* message) const;
  CompressionError SetDictionary();
  bool InitZlib();

  Mutex mutex_;  // Protects zlib_init_done_.
  bool zlib_init_done_ = false;
  int err_ = 0;
  int flush_ = 0;
  int level_ = 0;
  int mem_level_ = 0;
  node_zlib_mode mode_ = NONE;
  int strategy_ = 0;
  int window_bits_ = 0;
  unsigned int gzip_id_bytes_read_ = 0;
  std::vector<unsigned char> dictionary_;

  z_stream strm_;
};

// Brotli has different data types for compression and decompression streams,
// so some of the specifics are implemented in more specific subclasses
class BrotliContext : public MemoryRetainer {
 public:
  BrotliContext() = default;

  void SetBuffers(char* in, uint32_t in_len, char* out, uint32_t out_len);
  void SetFlush(int flush);
  void GetAfterWriteOffsets(uint32_t* avail_in, uint32_t* avail_out) const;
  inline void SetMode(node_zlib_mode mode) { mode_ = mode; }

  BrotliContext(const BrotliContext&) = delete;
  BrotliContext& operator=(const BrotliContext&) = delete;

 protected:
  node_zlib_mode mode_ = NONE;
  uint8_t* next_in_ = nullptr;
  uint8_t* next_out_ = nullptr;
  size_t avail_in_ = 0;
  size_t avail_out_ = 0;
  BrotliEncoderOperation flush_ = BROTLI_OPERATION_PROCESS;
  // TODO(addaleax): These should not need to be stored here.
  // This is currently only done this way to make implementing ResetStream()
  // easier.
  brotli_alloc_func alloc_ = nullptr;
  brotli_free_func free_ = nullptr;
  void* alloc_opaque_ = nullptr;
};

class BrotliEncoderContext final : public BrotliContext {
 public:
  void Close();
  void DoThreadPoolWork();
  CompressionError Init(brotli_alloc_func alloc,
                        brotli_free_func free,
                        void* opaque);
  CompressionError ResetStream();
  CompressionError SetParams(int key, uint32_t value);
  CompressionError GetErrorInfo() const;

  SET_MEMORY_INFO_NAME(BrotliEncoderContext)
  SET_SELF_SIZE(BrotliEncoderContext)
  SET_NO_MEMORY_INFO()  // state_ is covered through allocation tracking.

 private:
  bool last_result_ = false;
  DeleteFnPtr<BrotliEncoderState, BrotliEncoderDestroyInstance> state_;
};

class BrotliDecoderContext final : public BrotliContext {
 public:
  void Close();
  void DoThreadPoolWork();
  CompressionError Init(brotli_alloc_func alloc,
                        brotli_free_func free,
                        void* opaque);
  CompressionError ResetStream();
  CompressionError SetParams(int key, uint32_t value);
  CompressionError GetErrorInfo() const;

  SET_MEMORY_INFO_NAME(BrotliDecoderContext)
  SET_SELF_SIZE(BrotliDecoderContext)
  SET_NO_MEMORY_INFO()  // state_ is covered through allocation tracking.

 private:
  BrotliDecoderResult last_result_ = BROTLI_DECODER_RESULT_SUCCESS;
  BrotliDecoderErrorCode error_ = BROTLI_DECODER_NO_ERROR;
  std::string error_string_;
  DeleteFnPtr<BrotliDecoderState, BrotliDecoderDestroyInstance> state_;
};

template <typename CompressionContext>
class CompressionStream : public AsyncWrap, public ThreadPoolWork {
 public:
  CompressionStream(Environment* env, Local<Object> wrap)
      : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_ZLIB),
        ThreadPoolWork(env),
        write_result_(nullptr) {
    MakeWeak();
  }

  ~CompressionStream() override {
    CHECK_EQ(false, write_in_progress_ && "write in progress");
    Close();
    CHECK_EQ(zlib_memory_, 0);
    CHECK_EQ(unreported_allocations_, 0);
  }

  void Close() {
    if (write_in_progress_) {
      pending_close_ = true;
      return;
    }

    pending_close_ = false;
    closed_ = true;
    CHECK(init_done_ && "close before init");

    AllocScope alloc_scope(this);
    ctx_.Close();
  }


  static void Close(const FunctionCallbackInfo<Value>& args) {
    CompressionStream* ctx;
    ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
    ctx->Close();
  }


  // write(flush, in, in_off, in_len, out, out_off, out_len)
  template <bool async>
  static void Write(const FunctionCallbackInfo<Value>& args) {
    Environment* env = Environment::GetCurrent(args);
    Local<Context> context = env->context();
    CHECK_EQ(args.Length(), 7);

    uint32_t in_off, in_len, out_off, out_len, flush;
    char* in;
    char* out;

    CHECK_EQ(false, args[0]->IsUndefined() && "must provide flush value");
    if (!args[0]->Uint32Value(context).To(&flush)) return;

    if (flush != Z_NO_FLUSH &&
        flush != Z_PARTIAL_FLUSH &&
        flush != Z_SYNC_FLUSH &&
        flush != Z_FULL_FLUSH &&
        flush != Z_FINISH &&
        flush != Z_BLOCK) {
      CHECK(0 && "Invalid flush value");
    }

    if (args[1]->IsNull()) {
      // just a flush
      in = nullptr;
      in_len = 0;
      in_off = 0;
    } else {
      CHECK(Buffer::HasInstance(args[1]));
      Local<Object> in_buf = args[1].As<Object>();
      if (!args[2]->Uint32Value(context).To(&in_off)) return;
      if (!args[3]->Uint32Value(context).To(&in_len)) return;

      CHECK(Buffer::IsWithinBounds(in_off, in_len, Buffer::Length(in_buf)));
      in = Buffer::Data(in_buf) + in_off;
    }

    CHECK(Buffer::HasInstance(args[4]));
    Local<Object> out_buf = args[4].As<Object>();
    if (!args[5]->Uint32Value(context).To(&out_off)) return;
    if (!args[6]->Uint32Value(context).To(&out_len)) return;
    CHECK(Buffer::IsWithinBounds(out_off, out_len, Buffer::Length(out_buf)));
    out = Buffer::Data(out_buf) + out_off;

    CompressionStream* ctx;
    ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

    ctx->Write<async>(flush, in, in_len, out, out_len);
  }

  template <bool async>
  void Write(uint32_t flush,
             char* in, uint32_t in_len,
             char* out, uint32_t out_len) {
    AllocScope alloc_scope(this);

    CHECK(init_done_ && "write before init");
    CHECK(!closed_ && "already finalized");

    CHECK_EQ(false, write_in_progress_);
    CHECK_EQ(false, pending_close_);
    write_in_progress_ = true;
    Ref();

    ctx_.SetBuffers(in, in_len, out, out_len);
    ctx_.SetFlush(flush);

    if (!async) {
      // sync version
      AsyncWrap::env()->PrintSyncTrace();
      DoThreadPoolWork();
      if (CheckError()) {
        UpdateWriteResult();
        write_in_progress_ = false;
      }
      Unref();
      return;
    }

    // async version
    ScheduleWork();
  }

  void UpdateWriteResult() {
    ctx_.GetAfterWriteOffsets(&write_result_[1], &write_result_[0]);
  }

  // thread pool!
  // This function may be called multiple times on the uv_work pool
  // for a single write() call, until all of the input bytes have
  // been consumed.
  void DoThreadPoolWork() override {
    ctx_.DoThreadPoolWork();
  }


  bool CheckError() {
    const CompressionError err = ctx_.GetErrorInfo();
    if (!err.IsError()) return true;
    EmitError(err);
    return false;
  }


  // v8 land!
  void AfterThreadPoolWork(int status) override {
    AllocScope alloc_scope(this);
    auto on_scope_leave = OnScopeLeave([&]() { Unref(); });

    write_in_progress_ = false;

    if (status == UV_ECANCELED) {
      Close();
      return;
    }

    CHECK_EQ(status, 0);

    Environment* env = AsyncWrap::env();
    HandleScope handle_scope(env->isolate());
    Context::Scope context_scope(env->context());

    if (!CheckError())
      return;

    UpdateWriteResult();

    // call the write() cb
    Local<Function> cb = PersistentToLocal::Default(env->isolate(),
                                                    write_js_callback_);
    MakeCallback(cb, 0, nullptr);

    if (pending_close_)
      Close();
  }

  // TODO(addaleax): Switch to modern error system (node_errors.h).
  void EmitError(const CompressionError& err) {
    Environment* env = AsyncWrap::env();
    // If you hit this assertion, you forgot to enter the v8::Context first.
    CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());

    HandleScope scope(env->isolate());
    Local<Value> args[3] = {
      OneByteString(env->isolate(), err.message),
      Integer::New(env->isolate(), err.err),
      OneByteString(env->isolate(), err.code)
    };
    MakeCallback(env->onerror_string(), arraysize(args), args);

    // no hope of rescue.
    write_in_progress_ = false;
    if (pending_close_)
      Close();
  }

  static void Reset(const FunctionCallbackInfo<Value> &args) {
    CompressionStream* wrap;
    ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());

    AllocScope alloc_scope(wrap);
    const CompressionError err = wrap->context()->ResetStream();
    if (err.IsError())
      wrap->EmitError(err);
  }

  void MemoryInfo(MemoryTracker* tracker) const override {
    tracker->TrackField("compression context", ctx_);
    tracker->TrackFieldWithSize("zlib_memory",
                                zlib_memory_ + unreported_allocations_);
  }

 protected:
  CompressionContext* context() { return &ctx_; }

  void InitStream(uint32_t* write_result, Local<Function> write_js_callback) {
    write_result_ = write_result;
    write_js_callback_.Reset(AsyncWrap::env()->isolate(), write_js_callback);
    init_done_ = true;
  }

  // Allocation functions provided to zlib itself. We store the real size of
  // the allocated memory chunk just before the "payload" memory we return
  // to zlib.
  // Because we use zlib off the thread pool, we can not report memory directly
  // to V8; rather, we first store it as "unreported" memory in a separate
  // field and later report it back from the main thread.
  static void* AllocForZlib(void* data, uInt items, uInt size) {
    size_t real_size =
        MultiplyWithOverflowCheck(static_cast<size_t>(items),
                                  static_cast<size_t>(size));
    return AllocForBrotli(data, real_size);
  }

  static void* AllocForBrotli(void* data, size_t size) {
    size += sizeof(size_t);
    CompressionStream* ctx = static_cast<CompressionStream*>(data);
    char* memory = UncheckedMalloc(size);
    if (UNLIKELY(memory == nullptr)) return nullptr;
    *reinterpret_cast<size_t*>(memory) = size;
    ctx->unreported_allocations_.fetch_add(size,
                                           std::memory_order_relaxed);
    return memory + sizeof(size_t);
  }

  static void FreeForZlib(void* data, void* pointer) {
    if (UNLIKELY(pointer == nullptr)) return;
    CompressionStream* ctx = static_cast<CompressionStream*>(data);
    char* real_pointer = static_cast<char*>(pointer) - sizeof(size_t);
    size_t real_size = *reinterpret_cast<size_t*>(real_pointer);
    ctx->unreported_allocations_.fetch_sub(real_size,
                                           std::memory_order_relaxed);
    free(real_pointer);
  }

  // This is called on the main thread after zlib may have allocated something
  // in order to report it back to V8.
  void AdjustAmountOfExternalAllocatedMemory() {
    ssize_t report =
        unreported_allocations_.exchange(0, std::memory_order_relaxed);
    if (report == 0) return;
    CHECK_IMPLIES(report < 0, zlib_memory_ >= static_cast<size_t>(-report));
    zlib_memory_ += report;
    AsyncWrap::env()->isolate()->AdjustAmountOfExternalAllocatedMemory(report);
  }

  struct AllocScope {
    explicit AllocScope(CompressionStream* stream) : stream(stream) {}
    ~AllocScope() { stream->AdjustAmountOfExternalAllocatedMemory(); }
    CompressionStream* stream;
  };

 private:
  void Ref() {
    if (++refs_ == 1) {
      ClearWeak();
    }
  }

  void Unref() {
    CHECK_GT(refs_, 0);
    if (--refs_ == 0) {
      MakeWeak();
    }
  }

  bool init_done_ = false;
  bool write_in_progress_ = false;
  bool pending_close_ = false;
  bool closed_ = false;
  unsigned int refs_ = 0;
  uint32_t* write_result_ = nullptr;
  Global<Function> write_js_callback_;
  std::atomic<ssize_t> unreported_allocations_{0};
  size_t zlib_memory_ = 0;

  CompressionContext ctx_;
};

class ZlibStream : public CompressionStream<ZlibContext> {
 public:
  ZlibStream(Environment* env, Local<Object> wrap, node_zlib_mode mode)
    : CompressionStream(env, wrap) {
    context()->SetMode(mode);
  }

  static void New(const FunctionCallbackInfo<Value>& args) {
    Environment* env = Environment::GetCurrent(args);
    CHECK(args[0]->IsInt32());
    node_zlib_mode mode =
        static_cast<node_zlib_mode>(args[0].As<Int32>()->Value());
    new ZlibStream(env, args.This(), mode);
  }

  // just pull the ints out of the args and call the other Init
  static void Init(const FunctionCallbackInfo<Value>& args) {
    // Refs: https://github.com/nodejs/node/issues/16649
    // Refs: https://github.com/nodejs/node/issues/14161
    if (args.Length() == 5) {
      fprintf(stderr,
          "WARNING: You are likely using a version of node-tar or npm that "
          "is incompatible with this version of Node.js.\nPlease use "
          "either the version of npm that is bundled with Node.js, or "
          "a version of npm (> 5.5.1 or < 5.4.0) or node-tar (> 4.0.1) "
          "that is compatible with Node.js 9 and above.\n");
    }
    CHECK(args.Length() == 7 &&
      "init(windowBits, level, memLevel, strategy, writeResult, writeCallback,"
      " dictionary)");

    ZlibStream* wrap;
    ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());

    Local<Context> context = args.GetIsolate()->GetCurrentContext();

    // windowBits is special. On the compression side, 0 is an invalid value.
    // But on the decompression side, a value of 0 for windowBits tells zlib
    // to use the window size in the zlib header of the compressed stream.
    uint32_t window_bits;
    if (!args[0]->Uint32Value(context).To(&window_bits)) return;

    int32_t level;
    if (!args[1]->Int32Value(context).To(&level)) return;

    uint32_t mem_level;
    if (!args[2]->Uint32Value(context).To(&mem_level)) return;

    uint32_t strategy;
    if (!args[3]->Uint32Value(context).To(&strategy)) return;

    CHECK(args[4]->IsUint32Array());
    Local<Uint32Array> array = args[4].As<Uint32Array>();
    Local<ArrayBuffer> ab = array->Buffer();
    uint32_t* write_result = static_cast<uint32_t*>(
        ab->GetBackingStore()->Data());

    CHECK(args[5]->IsFunction());
    Local<Function> write_js_callback = args[5].As<Function>();

    std::vector<unsigned char> dictionary;
    if (Buffer::HasInstance(args[6])) {
      unsigned char* data =
          reinterpret_cast<unsigned char*>(Buffer::Data(args[6]));
      dictionary = std::vector<unsigned char>(
          data,
          data + Buffer::Length(args[6]));
    }

    wrap->InitStream(write_result, write_js_callback);

    AllocScope alloc_scope(wrap);
    wrap->context()->SetAllocationFunctions(
        AllocForZlib, FreeForZlib, static_cast<CompressionStream*>(wrap));
    wrap->context()->Init(level, window_bits, mem_level, strategy,
                          std::move(dictionary));
  }

  static void Params(const FunctionCallbackInfo<Value>& args) {
    CHECK(args.Length() == 2 && "params(level, strategy)");
    ZlibStream* wrap;
    ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
    Local<Context> context = args.GetIsolate()->GetCurrentContext();
    int level;
    if (!args[0]->Int32Value(context).To(&level)) return;
    int strategy;
    if (!args[1]->Int32Value(context).To(&strategy)) return;

    AllocScope alloc_scope(wrap);
    const CompressionError err = wrap->context()->SetParams(level, strategy);
    if (err.IsError())
      wrap->EmitError(err);
  }

  SET_MEMORY_INFO_NAME(ZlibStream)
  SET_SELF_SIZE(ZlibStream)
};

template <typename CompressionContext>
class BrotliCompressionStream : public CompressionStream<CompressionContext> {
 public:
  BrotliCompressionStream(Environment* env,
                          Local<Object> wrap,
                          node_zlib_mode mode)
    : CompressionStream<CompressionContext>(env, wrap) {
    context()->SetMode(mode);
  }

  inline CompressionContext* context() {
    return this->CompressionStream<CompressionContext>::context();
  }
  typedef typename CompressionStream<CompressionContext>::AllocScope AllocScope;

  static void New(const FunctionCallbackInfo<Value>& args) {
    Environment* env = Environment::GetCurrent(args);
    CHECK(args[0]->IsInt32());
    node_zlib_mode mode =
        static_cast<node_zlib_mode>(args[0].As<Int32>()->Value());
    new BrotliCompressionStream(env, args.This(), mode);
  }

  static void Init(const FunctionCallbackInfo<Value>& args) {
    BrotliCompressionStream* wrap;
    ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
    CHECK(args.Length() == 3 && "init(params, writeResult, writeCallback)");

    CHECK(args[1]->IsUint32Array());
    uint32_t* write_result = reinterpret_cast<uint32_t*>(Buffer::Data(args[1]));

    CHECK(args[2]->IsFunction());
    Local<Function> write_js_callback = args[2].As<Function>();
    wrap->InitStream(write_result, write_js_callback);

    AllocScope alloc_scope(wrap);
    CompressionError err =
        wrap->context()->Init(
          CompressionStream<CompressionContext>::AllocForBrotli,
          CompressionStream<CompressionContext>::FreeForZlib,
          static_cast<CompressionStream<CompressionContext>*>(wrap));
    if (err.IsError()) {
      wrap->EmitError(err);
      args.GetReturnValue().Set(false);
      return;
    }

    CHECK(args[0]->IsUint32Array());
    const uint32_t* data = reinterpret_cast<uint32_t*>(Buffer::Data(args[0]));
    size_t len = args[0].As<Uint32Array>()->Length();

    for (int i = 0; static_cast<size_t>(i) < len; i++) {
      if (data[i] == static_cast<uint32_t>(-1))
        continue;
      err = wrap->context()->SetParams(i, data[i]);
      if (err.IsError()) {
        wrap->EmitError(err);
        args.GetReturnValue().Set(false);
        return;
      }
    }

    args.GetReturnValue().Set(true);
  }

  static void Params(const FunctionCallbackInfo<Value>& args) {
    // Currently a no-op, and not accessed from JS land.
    // At some point Brotli may support changing parameters on the fly,
    // in which case we can implement this and a JS equivalent similar to
    // the zlib Params() function.
  }

  SET_MEMORY_INFO_NAME(BrotliCompressionStream)
  SET_SELF_SIZE(BrotliCompressionStream)
};

using BrotliEncoderStream = BrotliCompressionStream<BrotliEncoderContext>;
using BrotliDecoderStream = BrotliCompressionStream<BrotliDecoderContext>;

void ZlibContext::Close() {
  {
    Mutex::ScopedLock lock(mutex_);
    if (!zlib_init_done_) {
      dictionary_.clear();
      mode_ = NONE;
      return;
    }
  }

  CHECK_LE(mode_, UNZIP);

  int status = Z_OK;
  if (mode_ == DEFLATE || mode_ == GZIP || mode_ == DEFLATERAW) {
    status = deflateEnd(&strm_);
  } else if (mode_ == INFLATE || mode_ == GUNZIP || mode_ == INFLATERAW ||
             mode_ == UNZIP) {
    status = inflateEnd(&strm_);
  }

  CHECK(status == Z_OK || status == Z_DATA_ERROR);
  mode_ = NONE;

  dictionary_.clear();
}


void ZlibContext::DoThreadPoolWork() {
  bool first_init_call = InitZlib();
  if (first_init_call && err_ != Z_OK) {
    return;
  }

  const Bytef* next_expected_header_byte = nullptr;

  // If the avail_out is left at 0, then it means that it ran out
  // of room.  If there was avail_out left over, then it means
  // that all of the input was consumed.
  switch (mode_) {
    case DEFLATE:
    case GZIP:
    case DEFLATERAW:
      err_ = deflate(&strm_, flush_);
      break;
    case UNZIP:
      if (strm_.avail_in > 0) {
        next_expected_header_byte = strm_.next_in;
      }

      switch (gzip_id_bytes_read_) {
        case 0:
          if (next_expected_header_byte == nullptr) {
            break;
          }

          if (*next_expected_header_byte == GZIP_HEADER_ID1) {
            gzip_id_bytes_read_ = 1;
            next_expected_header_byte++;

            if (strm_.avail_in == 1) {
              // The only available byte was already read.
              break;
            }
          } else {
            mode_ = INFLATE;
            break;
          }

          // fallthrough
        case 1:
          if (next_expected_header_byte == nullptr) {
            break;
          }

          if (*next_expected_header_byte == GZIP_HEADER_ID2) {
            gzip_id_bytes_read_ = 2;
            mode_ = GUNZIP;
          } else {
            // There is no actual difference between INFLATE and INFLATERAW
            // (after initialization).
            mode_ = INFLATE;
          }

          break;
        default:
          CHECK(0 && "invalid number of gzip magic number bytes read");
      }

      // fallthrough
    case INFLATE:
    case GUNZIP:
    case INFLATERAW:
      err_ = inflate(&strm_, flush_);

      // If data was encoded with dictionary (INFLATERAW will have it set in
      // SetDictionary, don't repeat that here)
      if (mode_ != INFLATERAW &&
          err_ == Z_NEED_DICT &&
          !dictionary_.empty()) {
        // Load it
        err_ = inflateSetDictionary(&strm_,
                                    dictionary_.data(),
                                    dictionary_.size());
        if (err_ == Z_OK) {
          // And try to decode again
          err_ = inflate(&strm_, flush_);
        } else if (err_ == Z_DATA_ERROR) {
          // Both inflateSetDictionary() and inflate() return Z_DATA_ERROR.
          // Make it possible for After() to tell a bad dictionary from bad
          // input.
          err_ = Z_NEED_DICT;
        }
      }

      while (strm_.avail_in > 0 &&
             mode_ == GUNZIP &&
             err_ == Z_STREAM_END &&
             strm_.next_in[0] != 0x00) {
        // Bytes remain in input buffer. Perhaps this is another compressed
        // member in the same archive, or just trailing garbage.
        // Trailing zero bytes are okay, though, since they are frequently
        // used for padding.

        ResetStream();
        err_ = inflate(&strm_, flush_);
      }
      break;
    default:
      UNREACHABLE();
  }
}


void ZlibContext::SetBuffers(char* in, uint32_t in_len,
                             char* out, uint32_t out_len) {
  strm_.avail_in = in_len;
  strm_.next_in = reinterpret_cast<Bytef*>(in);
  strm_.avail_out = out_len;
  strm_.next_out = reinterpret_cast<Bytef*>(out);
}


void ZlibContext::SetFlush(int flush) {
  flush_ = flush;
}


void ZlibContext::GetAfterWriteOffsets(uint32_t* avail_in,
                                       uint32_t* avail_out) const {
  *avail_in = strm_.avail_in;
  *avail_out = strm_.avail_out;
}


CompressionError ZlibContext::ErrorForMessage(const char* message) const {
  if (strm_.msg != nullptr)
    message = strm_.msg;

  return CompressionError { message, ZlibStrerror(err_), err_ };
}


CompressionError ZlibContext::GetErrorInfo() const {
  // Acceptable error states depend on the type of zlib stream.
  switch (err_) {
  case Z_OK:
  case Z_BUF_ERROR:
    if (strm_.avail_out != 0 && flush_ == Z_FINISH) {
      return ErrorForMessage("unexpected end of file");
    }
  case Z_STREAM_END:
    // normal statuses, not fatal
    break;
  case Z_NEED_DICT:
    if (dictionary_.empty())
      return ErrorForMessage("Missing dictionary");
    else
      return ErrorForMessage("Bad dictionary");
  default:
    // something else.
    return ErrorForMessage("Zlib error");
  }

  return CompressionError {};
}


CompressionError ZlibContext::ResetStream() {
  bool first_init_call = InitZlib();
  if (first_init_call && err_ != Z_OK) {
    return ErrorForMessage("Failed to init stream before reset");
  }

  err_ = Z_OK;

  switch (mode_) {
    case DEFLATE:
    case DEFLATERAW:
    case GZIP:
      err_ = deflateReset(&strm_);
      break;
    case INFLATE:
    case INFLATERAW:
    case GUNZIP:
      err_ = inflateReset(&strm_);
      break;
    default:
      break;
  }

  if (err_ != Z_OK)
    return ErrorForMessage("Failed to reset stream");

  return SetDictionary();
}


void ZlibContext::SetAllocationFunctions(alloc_func alloc,
                                         free_func free,
                                         void* opaque) {
  strm_.zalloc = alloc;
  strm_.zfree = free;
  strm_.opaque = opaque;
}


void ZlibContext::Init(
    int level, int window_bits, int mem_level, int strategy,
    std::vector<unsigned char>&& dictionary) {
  if (!((window_bits == 0) &&
        (mode_ == INFLATE ||
         mode_ == GUNZIP ||
         mode_ == UNZIP))) {
    CHECK(
        (window_bits >= Z_MIN_WINDOWBITS && window_bits <= Z_MAX_WINDOWBITS) &&
        "invalid windowBits");
  }

  CHECK((level >= Z_MIN_LEVEL && level <= Z_MAX_LEVEL) &&
    "invalid compression level");

  CHECK((mem_level >= Z_MIN_MEMLEVEL && mem_level <= Z_MAX_MEMLEVEL) &&
        "invalid memlevel");

  CHECK((strategy == Z_FILTERED || strategy == Z_HUFFMAN_ONLY ||
         strategy == Z_RLE || strategy == Z_FIXED ||
         strategy == Z_DEFAULT_STRATEGY) &&
        "invalid strategy");

  level_ = level;
  window_bits_ = window_bits;
  mem_level_ = mem_level;
  strategy_ = strategy;

  flush_ = Z_NO_FLUSH;

  err_ = Z_OK;

  if (mode_ == GZIP || mode_ == GUNZIP) {
    window_bits_ += 16;
  }

  if (mode_ == UNZIP) {
    window_bits_ += 32;
  }

  if (mode_ == DEFLATERAW || mode_ == INFLATERAW) {
    window_bits_ *= -1;
  }

  dictionary_ = std::move(dictionary);
}

bool ZlibContext::InitZlib() {
  Mutex::ScopedLock lock(mutex_);
  if (zlib_init_done_) {
    return false;
  }

  switch (mode_) {
    case DEFLATE:
    case GZIP:
    case DEFLATERAW:
      err_ = deflateInit2(&strm_,
                          level_,
                          Z_DEFLATED,
                          window_bits_,
                          mem_level_,
                          strategy_);
      break;
    case INFLATE:
    case GUNZIP:
    case INFLATERAW:
    case UNZIP:
      err_ = inflateInit2(&strm_, window_bits_);
      break;
    default:
      UNREACHABLE();
  }

  if (err_ != Z_OK) {
    dictionary_.clear();
    mode_ = NONE;
    return true;
  }

  SetDictionary();
  zlib_init_done_ = true;
  return true;
}


CompressionError ZlibContext::SetDictionary() {
  if (dictionary_.empty())
    return CompressionError {};

  err_ = Z_OK;

  switch (mode_) {
    case DEFLATE:
    case DEFLATERAW:
      err_ = deflateSetDictionary(&strm_,
                                  dictionary_.data(),
                                  dictionary_.size());
      break;
    case INFLATERAW:
      // The other inflate cases will have the dictionary set when inflate()
      // returns Z_NEED_DICT in Process()
      err_ = inflateSetDictionary(&strm_,
                                  dictionary_.data(),
                                  dictionary_.size());
      break;
    default:
      break;
  }

  if (err_ != Z_OK) {
    return ErrorForMessage("Failed to set dictionary");
  }

  return CompressionError {};
}


CompressionError ZlibContext::SetParams(int level, int strategy) {
  bool first_init_call = InitZlib();
  if (first_init_call && err_ != Z_OK) {
    return ErrorForMessage("Failed to init stream before set parameters");
  }

  err_ = Z_OK;

  switch (mode_) {
    case DEFLATE:
    case DEFLATERAW:
      err_ = deflateParams(&strm_, level, strategy);
      break;
    default:
      break;
  }

  if (err_ != Z_OK && err_ != Z_BUF_ERROR) {
    return ErrorForMessage("Failed to set parameters");
  }

  return CompressionError {};
}


void BrotliContext::SetBuffers(char* in, uint32_t in_len,
                               char* out, uint32_t out_len) {
  next_in_ = reinterpret_cast<uint8_t*>(in);
  next_out_ = reinterpret_cast<uint8_t*>(out);
  avail_in_ = in_len;
  avail_out_ = out_len;
}


void BrotliContext::SetFlush(int flush) {
  flush_ = static_cast<BrotliEncoderOperation>(flush);
}


void BrotliContext::GetAfterWriteOffsets(uint32_t* avail_in,
                                         uint32_t* avail_out) const {
  *avail_in = avail_in_;
  *avail_out = avail_out_;
}


void BrotliEncoderContext::DoThreadPoolWork() {
  CHECK_EQ(mode_, BROTLI_ENCODE);
  CHECK(state_);
  const uint8_t* next_in = next_in_;
  last_result_ = BrotliEncoderCompressStream(state_.get(),
                                             flush_,
                                             &avail_in_,
                                             &next_in,
                                             &avail_out_,
                                             &next_out_,
                                             nullptr);
  next_in_ += next_in - next_in_;
}


void BrotliEncoderContext::Close() {
  state_.reset();
  mode_ = NONE;
}

CompressionError BrotliEncoderContext::Init(brotli_alloc_func alloc,
                                            brotli_free_func free,
                                            void* opaque) {
  alloc_ = alloc;
  free_ = free;
  alloc_opaque_ = opaque;
  state_.reset(BrotliEncoderCreateInstance(alloc, free, opaque));
  if (!state_) {
    return CompressionError("Could not initialize Brotli instance",
                            "ERR_ZLIB_INITIALIZATION_FAILED",
                            -1);
  } else {
    return CompressionError {};
  }
}

CompressionError BrotliEncoderContext::ResetStream() {
  return Init(alloc_, free_, alloc_opaque_);
}

CompressionError BrotliEncoderContext::SetParams(int key, uint32_t value) {
  if (!BrotliEncoderSetParameter(state_.get(),
                                 static_cast<BrotliEncoderParameter>(key),
                                 value)) {
    return CompressionError("Setting parameter failed",
                            "ERR_BROTLI_PARAM_SET_FAILED",
                            -1);
  } else {
    return CompressionError {};
  }
}

CompressionError BrotliEncoderContext::GetErrorInfo() const {
  if (!last_result_) {
    return CompressionError("Compression failed",
                            "ERR_BROTLI_COMPRESSION_FAILED",
                            -1);
  } else {
    return CompressionError {};
  }
}


void BrotliDecoderContext::Close() {
  state_.reset();
  mode_ = NONE;
}

void BrotliDecoderContext::DoThreadPoolWork() {
  CHECK_EQ(mode_, BROTLI_DECODE);
  CHECK(state_);
  const uint8_t* next_in = next_in_;
  last_result_ = BrotliDecoderDecompressStream(state_.get(),
                                               &avail_in_,
                                               &next_in,
                                               &avail_out_,
                                               &next_out_,
                                               nullptr);
  next_in_ += next_in - next_in_;
  if (last_result_ == BROTLI_DECODER_RESULT_ERROR) {
    error_ = BrotliDecoderGetErrorCode(state_.get());
    error_string_ = std::string("ERR_") + BrotliDecoderErrorString(error_);
  }
}

CompressionError BrotliDecoderContext::Init(brotli_alloc_func alloc,
                                            brotli_free_func free,
                                            void* opaque) {
  alloc_ = alloc;
  free_ = free;
  alloc_opaque_ = opaque;
  state_.reset(BrotliDecoderCreateInstance(alloc, free, opaque));
  if (!state_) {
    return CompressionError("Could not initialize Brotli instance",
                            "ERR_ZLIB_INITIALIZATION_FAILED",
                            -1);
  } else {
    return CompressionError {};
  }
}

CompressionError BrotliDecoderContext::ResetStream() {
  return Init(alloc_, free_, alloc_opaque_);
}

CompressionError BrotliDecoderContext::SetParams(int key, uint32_t value) {
  if (!BrotliDecoderSetParameter(state_.get(),
                                 static_cast<BrotliDecoderParameter>(key),
                                 value)) {
    return CompressionError("Setting parameter failed",
                            "ERR_BROTLI_PARAM_SET_FAILED",
                            -1);
  } else {
    return CompressionError {};
  }
}

CompressionError BrotliDecoderContext::GetErrorInfo() const {
  if (error_ != BROTLI_DECODER_NO_ERROR) {
    return CompressionError("Decompression failed",
                            error_string_.c_str(),
                            static_cast<int>(error_));
  } else if (flush_ == BROTLI_OPERATION_FINISH &&
             last_result_ == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
    // Match zlib's behaviour, as brotli doesn't have its own code for this.
    return CompressionError("unexpected end of file",
                            "Z_BUF_ERROR",
                            Z_BUF_ERROR);
  } else {
    return CompressionError {};
  }
}


template <typename Stream>
struct MakeClass {
  static void Make(Environment* env, Local<Object> target, const char* name) {
    Local<FunctionTemplate> z = env->NewFunctionTemplate(Stream::New);

    z->InstanceTemplate()->SetInternalFieldCount(
        Stream::kInternalFieldCount);
    z->Inherit(AsyncWrap::GetConstructorTemplate(env));

    env->SetProtoMethod(z, "write", Stream::template Write<true>);
    env->SetProtoMethod(z, "writeSync", Stream::template Write<false>);
    env->SetProtoMethod(z, "close", Stream::Close);

    env->SetProtoMethod(z, "init", Stream::Init);
    env->SetProtoMethod(z, "params", Stream::Params);
    env->SetProtoMethod(z, "reset", Stream::Reset);

    Local<String> zlibString = OneByteString(env->isolate(), name);
    z->SetClassName(zlibString);
    target->Set(env->context(),
                zlibString,
                z->GetFunction(env->context()).ToLocalChecked()).Check();
  }
};

void Initialize(Local<Object> target,
                Local<Value> unused,
                Local<Context> context,
                void* priv) {
  Environment* env = Environment::GetCurrent(context);

  MakeClass<ZlibStream>::Make(env, target, "Zlib");
  MakeClass<BrotliEncoderStream>::Make(env, target, "BrotliEncoder");
  MakeClass<BrotliDecoderStream>::Make(env, target, "BrotliDecoder");

  target->Set(env->context(),
              FIXED_ONE_BYTE_STRING(env->isolate(), "ZLIB_VERSION"),
              FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION)).Check();
}

}  // anonymous namespace

void DefineZlibConstants(Local<Object> target) {
  NODE_DEFINE_CONSTANT(target, Z_NO_FLUSH);
  NODE_DEFINE_CONSTANT(target, Z_PARTIAL_FLUSH);
  NODE_DEFINE_CONSTANT(target, Z_SYNC_FLUSH);
  NODE_DEFINE_CONSTANT(target, Z_FULL_FLUSH);
  NODE_DEFINE_CONSTANT(target, Z_FINISH);
  NODE_DEFINE_CONSTANT(target, Z_BLOCK);

  // return/error codes
  NODE_DEFINE_CONSTANT(target, Z_OK);
  NODE_DEFINE_CONSTANT(target, Z_STREAM_END);
  NODE_DEFINE_CONSTANT(target, Z_NEED_DICT);
  NODE_DEFINE_CONSTANT(target, Z_ERRNO);
  NODE_DEFINE_CONSTANT(target, Z_STREAM_ERROR);
  NODE_DEFINE_CONSTANT(target, Z_DATA_ERROR);
  NODE_DEFINE_CONSTANT(target, Z_MEM_ERROR);
  NODE_DEFINE_CONSTANT(target, Z_BUF_ERROR);
  NODE_DEFINE_CONSTANT(target, Z_VERSION_ERROR);

  NODE_DEFINE_CONSTANT(target, Z_NO_COMPRESSION);
  NODE_DEFINE_CONSTANT(target, Z_BEST_SPEED);
  NODE_DEFINE_CONSTANT(target, Z_BEST_COMPRESSION);
  NODE_DEFINE_CONSTANT(target, Z_DEFAULT_COMPRESSION);
  NODE_DEFINE_CONSTANT(target, Z_FILTERED);
  NODE_DEFINE_CONSTANT(target, Z_HUFFMAN_ONLY);
  NODE_DEFINE_CONSTANT(target, Z_RLE);
  NODE_DEFINE_CONSTANT(target, Z_FIXED);
  NODE_DEFINE_CONSTANT(target, Z_DEFAULT_STRATEGY);
  NODE_DEFINE_CONSTANT(target, ZLIB_VERNUM);

  NODE_DEFINE_CONSTANT(target, DEFLATE);
  NODE_DEFINE_CONSTANT(target, INFLATE);
  NODE_DEFINE_CONSTANT(target, GZIP);
  NODE_DEFINE_CONSTANT(target, GUNZIP);
  NODE_DEFINE_CONSTANT(target, DEFLATERAW);
  NODE_DEFINE_CONSTANT(target, INFLATERAW);
  NODE_DEFINE_CONSTANT(target, UNZIP);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODE);
  NODE_DEFINE_CONSTANT(target, BROTLI_ENCODE);

  NODE_DEFINE_CONSTANT(target, Z_MIN_WINDOWBITS);
  NODE_DEFINE_CONSTANT(target, Z_MAX_WINDOWBITS);
  NODE_DEFINE_CONSTANT(target, Z_DEFAULT_WINDOWBITS);
  NODE_DEFINE_CONSTANT(target, Z_MIN_CHUNK);
  NODE_DEFINE_CONSTANT(target, Z_MAX_CHUNK);
  NODE_DEFINE_CONSTANT(target, Z_DEFAULT_CHUNK);
  NODE_DEFINE_CONSTANT(target, Z_MIN_MEMLEVEL);
  NODE_DEFINE_CONSTANT(target, Z_MAX_MEMLEVEL);
  NODE_DEFINE_CONSTANT(target, Z_DEFAULT_MEMLEVEL);
  NODE_DEFINE_CONSTANT(target, Z_MIN_LEVEL);
  NODE_DEFINE_CONSTANT(target, Z_MAX_LEVEL);
  NODE_DEFINE_CONSTANT(target, Z_DEFAULT_LEVEL);

  // Brotli constants
  NODE_DEFINE_CONSTANT(target, BROTLI_OPERATION_PROCESS);
  NODE_DEFINE_CONSTANT(target, BROTLI_OPERATION_FLUSH);
  NODE_DEFINE_CONSTANT(target, BROTLI_OPERATION_FINISH);
  NODE_DEFINE_CONSTANT(target, BROTLI_OPERATION_EMIT_METADATA);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_MODE);
  NODE_DEFINE_CONSTANT(target, BROTLI_MODE_GENERIC);
  NODE_DEFINE_CONSTANT(target, BROTLI_MODE_TEXT);
  NODE_DEFINE_CONSTANT(target, BROTLI_MODE_FONT);
  NODE_DEFINE_CONSTANT(target, BROTLI_DEFAULT_MODE);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_QUALITY);
  NODE_DEFINE_CONSTANT(target, BROTLI_MIN_QUALITY);
  NODE_DEFINE_CONSTANT(target, BROTLI_MAX_QUALITY);
  NODE_DEFINE_CONSTANT(target, BROTLI_DEFAULT_QUALITY);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_LGWIN);
  NODE_DEFINE_CONSTANT(target, BROTLI_MIN_WINDOW_BITS);
  NODE_DEFINE_CONSTANT(target, BROTLI_MAX_WINDOW_BITS);
  NODE_DEFINE_CONSTANT(target, BROTLI_LARGE_MAX_WINDOW_BITS);
  NODE_DEFINE_CONSTANT(target, BROTLI_DEFAULT_WINDOW);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_LGBLOCK);
  NODE_DEFINE_CONSTANT(target, BROTLI_MIN_INPUT_BLOCK_BITS);
  NODE_DEFINE_CONSTANT(target, BROTLI_MAX_INPUT_BLOCK_BITS);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_SIZE_HINT);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_LARGE_WINDOW);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_NPOSTFIX);
  NODE_DEFINE_CONSTANT(target, BROTLI_PARAM_NDIRECT);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_RESULT_ERROR);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_RESULT_SUCCESS);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT);
  NODE_DEFINE_CONSTANT(target,
      BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_PARAM_LARGE_WINDOW);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_NO_ERROR);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_SUCCESS);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_NEEDS_MORE_INPUT);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_NEEDS_MORE_OUTPUT);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_RESERVED);
  NODE_DEFINE_CONSTANT(target,
      BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE);
  NODE_DEFINE_CONSTANT(target,
      BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_CL_SPACE);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_TRANSFORM);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_DICTIONARY);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_PADDING_1);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_PADDING_2);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_FORMAT_DISTANCE);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_INVALID_ARGUMENTS);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES);
  NODE_DEFINE_CONSTANT(target, BROTLI_DECODER_ERROR_UNREACHABLE);
}

}  // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(zlib, node::Initialize)
