#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PY_SSIZE_T_CLEAN 1
#include <Python.h>
#include <bytesobject.h>
#include <structmember.h>

#include <brotli/types.h>
#include <brotli/decode.h>
#include <brotli/encode.h>

// 3.9  end-of-life is 2025-10-31.
// 3.10 end-of-life is 2026-10.
// 3.11 end-of-life is 2027-10.
// 3.12 end-of-life is 2028-10.
// 3.13 end-of-life is 2029-10.
// 3.14 end-of-life is 2030-10.
#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 10)
#error "Only Python 3.10+ is supported"
#endif

/*
Decoder / encoder nature does not support concurrent access. Attempt to enter
concurrently will result in an exception.

"Critical" parts used in prologues to ensure that only one thread enters.
For consistency, we use them in epilogues as well. "Critical" is essential for
free-threaded. In GIL environment those rendered as a scope (i.e. `{` and `}`).

NB: `Py_BEGIN_ALLOW_THREADS` / `Py_END_ALLOW_THREADS` are still required to
unblock the stop-the-world GC.
*/
#ifdef Py_GIL_DISABLED
#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 13)
#error "Critical sections are only available in Python 3.13+"
#endif
#define BROTLI_CRITICAL_START Py_BEGIN_CRITICAL_SECTION(self)
#define BROTLI_CRITICAL_END Py_END_CRITICAL_SECTION()
#else
#define BROTLI_CRITICAL_START {
#define BROTLI_CRITICAL_END }
#endif

static const char kErrorAttr[] = "error";
static const char kModuleAttr[] = "_module";

static const char kInvalidBufferError[] =
    "brotli: data must be a C-contiguous buffer";
static const char kOomError[] = "brotli: unable to allocate memory";
static const char kCompressCreateError[] =
    "brotli: failed to create native encoder instance";
static const char kCompressUnhealthyError[] = "brotli: encoder is unhealthy";
static const char kCompressConcurrentError[] =
    "brotli: encoder concurrent access";
static const char kCompressError[] = "brotli: encoder failed";
static const char kInvalidModeError[] = "brotli: invalid mode";
static const char kInvalidQualityError[] =
    "brotli: invalid quality; range is 0 to 11";
static const char kInvalidLgwinError[] =
    "brotli: invalid lgwin; range is 10 to 24";
static const char kInvalidLgblockError[] =
    "brotli: invalid lgblock; range is 16 to 24, or 0";
static const char kDecompressCreateError[] =
    "brotli: failed to create native decoder instance";
static const char kDecompressUnhealthyError[] = "brotli: decoder is unhealthy";
static const char kDecompressConcurrentError[] =
    "brotli: decoder concurrent access";
static const char kDecompressSinkError[] =
    "brotli: decoder process called with data when 'can_accept_more_data()' is "
    "False";
static const char kDecompressError[] = "brotli: decoder failed";

/* clang-format off */
PyDoc_STRVAR(brotli_error_doc,
"An error occurred in the Brotli implementation.");
PyDoc_STRVAR(brotli_Compressor_doc,
"An object to compress a byte string.\n"
"\n"
"Signature:\n"
"  Compressor(mode=MODE_GENERIC, quality=11, lgwin=22, lgblock=0)\n"
"\n"
"Args:\n"
"  mode (int): The compression mode can be MODE_GENERIC (default),\n"
"    MODE_TEXT (for UTF-8 format text input) or MODE_FONT (for WOFF 2.0).\n"
"  quality (int): Controls the compression-speed vs compression-\n"
"    density tradeoff. The higher the quality, the slower the compression.\n"
"    Must be in [0 .. 11]. Defaults to 11.\n"
"  lgwin (int): Base 2 logarithm of the sliding window size.\n"
"    Must be in [10 .. 24]. Defaults to 22.\n"
"  lgblock (int): Base 2 logarithm of the maximum input block size.\n"
"    Must be 0 or in [16 .. 24]. If set to 0, the value will be set based\n"
"    on the quality. Defaults to 0.\n"
"\n"
"Raises:\n"
"  brotli.error: If arguments are invalid.\n");
PyDoc_STRVAR(brotli_Compressor_process_doc,
"Process 'data' for compression, returning a bytes-object that contains\n"
"compressed output data. This data should be concatenated to the output\n"
"produced by any preceding calls to the 'process()' or 'flush()' methods.\n"
"Some or all of the input may be kept in internal buffers for later\n"
"processing, and the compressed output data may be empty until enough input\n"
"has been accumulated.\n"
"\n"
"Signature:\n"
"  process(data) -> bytes\n"
"\n"
"Args:\n"
"  data (bytes): The input data;\n"
"                MUST provide C-contiguous one-dimensional bytes view.\n"
"\n"
"Returns:\n"
"  The compressed output data (bytes)\n"
"\n"
"Raises:\n"
"  brotli.error: If compression fails\n");
PyDoc_STRVAR(brotli_Compressor_flush_doc,
"Process all pending input, returning a bytes-object containing the remaining\n"
"compressed data. This data should be concatenated to the output produced by\n"
"any preceding calls to the 'process()' or 'flush()' methods.\n"
"\n"
"Signature:\n"
"  flush() -> bytes\n"
"\n"
"Returns:\n"
"  The compressed output data (bytes)\n"
"\n"
"Raises:\n"
"  brotli.error: If compression fails\n");
PyDoc_STRVAR(brotli_Compressor_finish_doc,
"Process all pending input and complete all compression, returning\n"
"a 'bytes'-object containing the remaining compressed data. This data\n"
"should be concatenated to the output produced by any preceding calls\n"
"to the 'process()' or 'flush()' methods.\n"
"After calling 'finish()', the 'process()' and 'flush()' methods\n"
"cannot be called again, and a new \"Compressor\" object should be created.\n"
"\n"
"Signature:\n"
"  finish() -> bytes\n"
"\n"
"Returns:\n"
"  The compressed output data (bytes)\n"
"\n"
"Raises:\n"
"  brotli.error: If compression fails\n");
PyDoc_STRVAR(brotli_Decompressor_doc,
"An object to decompress a byte string.\n"
"\n"
"Signature:\n"
"  Decompressor()\n"
"\n"
"Raises:\n"
"  brotli.error: If arguments are invalid.\n");
PyDoc_STRVAR(brotli_Decompressor_process_doc,
"Process 'data' for decompression, returning a bytes-object that contains \n"
"decompressed output data. This data should be concatenated to the output\n"
"produced by any preceding calls to the 'process()' method.\n"
"Some or all of the input may be kept in internal buffers for later\n"
"processing, and the decompressed output data may be empty until enough input\n"
"has been accumulated.\n"
"\n"
"Signature:\n"
"  process(data, output_buffer_limit=int) -> bytes\n"
"\n"
"Args:\n"
"  data (bytes): The input data;\n"
"                MUST provide C-contiguous one-dimensional bytes view.\n"
"  output_buffer_limit (int): The maximum size of the output buffer.\n"
"                If set, the output buffer will not grow once its size\n"
"                equal or exceeding that value. If the limit is reached,\n"
"                further calls to process (potentially with empty input) will\n"
"                continue to yield more data. Following 'process()' must only\n"
"                be called with empty input until 'can_accept_more_data()'\n"
"                once returns True.\n"
"\n"
"Returns:\n"
"  The decompressed output data (bytes)\n"
"\n"
"Raises:\n"
"  brotli.error: If decompression fails\n");
PyDoc_STRVAR(brotli_Decompressor_is_finished_doc,
"Checks if decoder instance reached the final state.\n"
"\n"
"Signature:\n"
"  is_finished() -> bool\n"
"\n"
"Returns:\n"
"  True  if the decoder is in a state where it reached the end of the input\n"
"        and produced all of the output\n"
"  False otherwise\n");
PyDoc_STRVAR(brotli_Decompressor_can_accept_more_data_doc,
"Checks if the decoder instance can accept more compressed data.\n"
"If the 'process()' method on this instance of decompressor was never\n"
"called with 'output_buffer_limit', this method will always return True.\n"
"\n"
"Signature:"
"  can_accept_more_data() -> bool\n"
"\n"
"Returns:\n"
"  True  if the decoder is ready to accept more compressed data via\n"
"        'process()'\n"
"  False if the decoder needs to output some data via 'process(b'')'\n"
"        before being provided any more compressed data\n");
PyDoc_STRVAR(brotli_decompress__doc__,
"Decompress a compressed byte string.\n"
"\n"
"Signature:\n"
"  decompress(data) -> bytes\n"
"\n"
"Args:\n"
"  data (bytes): The input data;\n"
"                MUST provide C-contiguous one-dimensional bytes view.\n"
"\n"
"Returns:\n"
"  The decompressed byte string.\n"
"\n"
"Raises:\n"
"  brotli.error: If decompressor fails.\n");
PyDoc_STRVAR(brotli_doc,
"Implementation module for the Brotli library.");
/* clang-format on */

static void set_brotli_exception(PyObject* t, const char* msg) {
  PyObject* error = NULL;
  PyObject* module = NULL;
  assert(t != NULL);
  assert(PyType_Check(t));
  module = PyObject_GetAttrString(t, kModuleAttr);
  if (!module) return; /* AttributeError raised. */
  error = PyObject_GetAttrString(module, kErrorAttr);
  Py_DECREF(module);
  if (error == NULL) return; /* AttributeError raised. */
  PyErr_SetString(error, msg);
  Py_DECREF(error);
}

static void set_brotli_exception_from_module(PyObject* m, const char* msg) {
  PyObject* error = NULL;
  assert(m != NULL);
  assert(PyModule_Check(m));
  error = PyObject_GetAttrString(m, kErrorAttr);
  if (error == NULL) return; /* AttributeError raised. */
  PyErr_SetString(error, msg);
  Py_DECREF(error);
}

/*
   Checks if the `object` provides a C-bytes buffer view.
   Returns non-zero on success.
   Returns zero and sets an exception on failure.
 */
static int get_data_view(PyObject* object, Py_buffer* view) {
  /* PyBUF_SIMPLE means: no shape, no strides, no sub-offsets. */
  if (PyObject_GetBuffer(object, view, PyBUF_SIMPLE) != 0) goto error;
  if (view->len == 0) return 1;
  /* https://docs.python.org/3/c-api/buffer.html:
     If shape is NULL as a result of a PyBUF_SIMPLE or a PyBUF_WRITABLE request,
    the consumer must disregard itemsize and assume itemsize == 1.*/
  if (((view->ndim == 0) || (view->ndim == 1)) && (view->shape == NULL) &&
      (view->strides == NULL)) {
    return 1;
  } else {
    PyBuffer_Release(view);
  }
error:
  PyErr_SetString(PyExc_TypeError, kInvalidBufferError);
  return 0;
}

/* --- Buffer --- */

typedef struct {
  size_t size;
  void* next; /* Block* */
  uint8_t payload[16];
} Block;

typedef struct {
  Block* head;
  Block* tail;
  size_t avail_out;
  uint8_t* next_out;
  size_t num_blocks;
  uint64_t total_allocated;
} Buffer;

static void Buffer_Init(Buffer* buffer) {
  buffer->head = NULL;
  buffer->tail = NULL;
  buffer->avail_out = 0;
  buffer->next_out = NULL;
  buffer->num_blocks = 0;
  buffer->total_allocated = 0;
}

/*
   Grow the buffer.

   Return 0 on success.
   Return -1 on failure, but do NOT raise an exception.
*/
static int Buffer_Grow(Buffer* buffer) {
  size_t log_size = buffer->num_blocks + 15;
  size_t size = 1 << (log_size > 24 ? 24 : log_size);
  size_t payload_size = size - offsetof(Block, payload);
  Block* block = NULL;

  assert(buffer->avail_out == 0);

  if (buffer->total_allocated >= PY_SSIZE_T_MAX - payload_size) return -1;

  assert(size > sizeof(Block));
  block = (Block*)malloc(size);
  if (block == NULL) return -1;
  block->size = payload_size;
  block->next = NULL;
  if (buffer->head == NULL) {
    buffer->head = block;
  } else {
    buffer->tail->next = block;
  }
  buffer->tail = block;
  buffer->next_out = block->payload;
  buffer->avail_out = payload_size;
  buffer->total_allocated += payload_size;
  buffer->num_blocks++;
  return 0;
}

static void Buffer_Cleanup(Buffer* buffer) {
  Block* block = NULL;
  if (buffer->head == NULL) return;
  block = buffer->head;
  buffer->head = NULL;
  while (block != NULL) {
    Block* next = block->next;
    block->next = NULL;
    free(block);
    block = next;
  }
}

/*
   Finish the buffer.

   Return a bytes object on success.
   Return NULL on OOM, but do NOT raise an exception.
*/
static PyObject* Buffer_Finish(Buffer* buffer) {
  uint64_t out_size = buffer->total_allocated - buffer->avail_out;
  Py_ssize_t len = (Py_ssize_t)out_size;
  PyObject* result = NULL;
  uint8_t* out = NULL;
  Py_ssize_t pos = 0;
  Block* block = NULL;
  size_t tail_len = 0;

  if ((uint64_t)len != out_size) {
    return NULL;
  }

  result = PyBytes_FromStringAndSize(NULL, len);
  if (result == NULL) {
    PyErr_Clear(); /* OOM exception will be raised by callers. */
    return NULL;
  }
  if (len == 0) return result;

  out = (uint8_t*)PyBytes_AS_STRING(result);
  block = buffer->head;
  while (block != buffer->tail) {
    memcpy(out + pos, block->payload, block->size);
    pos += block->size;
    block = block->next;
  }
  tail_len = block->size - buffer->avail_out;
  if (tail_len > 0) {
    memcpy(out + pos, block->payload, tail_len);
  }
  return result;
}

/* --- Compressor --- */

typedef struct {
  PyObject_HEAD BrotliEncoderState* enc;
  int healthy;
  int processing;
} PyBrotli_Compressor;

static PyObject* brotli_Compressor_new(PyTypeObject* type, PyObject* args,
                                       PyObject* keywds) {
  /* `tp_itemsize` is 0, so `nitems` could be 0. */
  PyBrotli_Compressor* self = (PyBrotli_Compressor*)type->tp_alloc(type, 0);
  PyObject* self_type = (PyObject*)type;

  if (self == NULL) return NULL;

  self->healthy = 0;
  self->processing = 0;
  self->enc = BrotliEncoderCreateInstance(0, 0, 0);
  if (self->enc == NULL) {
    set_brotli_exception(self_type, kCompressCreateError);
    Py_TYPE(self)->tp_free((PyObject*)self);
    return NULL;
  }
  self->healthy = 1;

  return (PyObject*)self;
}

static int brotli_Compressor_init(PyBrotli_Compressor* self, PyObject* args,
                                  PyObject* keywds) {
  static const char* kwlist[] = {"mode", "quality", "lgwin", "lgblock", NULL};

  PyObject* self_type = (PyObject*)Py_TYPE((PyObject*)self);
  unsigned char mode = BROTLI_DEFAULT_MODE;
  unsigned char quality = BROTLI_DEFAULT_QUALITY;
  unsigned char lgwin = BROTLI_DEFAULT_WINDOW;
  unsigned char lgblock = 0;

  int ok = PyArg_ParseTupleAndKeywords(args, keywds, "|bbbb:Compressor",
                                       (char**)kwlist, &mode, &quality, &lgwin,
                                       &lgblock);

  assert(self->healthy);

  if (!ok) {
    self->healthy = 0;
    return -1;
  }

  if ((mode == 0) || (mode == 1) || (mode == 2)) {
    BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_MODE, (uint32_t)mode);
  } else {
    set_brotli_exception(self_type, kInvalidModeError);
    self->healthy = 0;
    return -1;
  }
  if (quality <= 11) {
    BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_QUALITY,
                              (uint32_t)quality);
  } else {
    set_brotli_exception(self_type, kInvalidQualityError);
    self->healthy = 0;
    return -1;
  }
  if ((10 <= lgwin) && (lgwin <= 24)) {
    BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_LGWIN, (uint32_t)lgwin);
  } else {
    set_brotli_exception(self_type, kInvalidLgwinError);
    self->healthy = 0;
    return -1;
  }
  if ((lgblock == 0) || ((16 <= lgblock) && (lgblock <= 24))) {
    BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_LGBLOCK,
                              (uint32_t)lgblock);
  } else {
    set_brotli_exception(self_type, kInvalidLgblockError);
    self->healthy = 0;
    return -1;
  }

  return 0;
}

static void brotli_Compressor_dealloc(PyBrotli_Compressor* self) {
  if (self->enc) BrotliEncoderDestroyInstance(self->enc);
  Py_TYPE(self)->tp_free((PyObject*)self);
}

static int brotli_compressor_enter(PyBrotli_Compressor* self) {
  PyObject* self_type = (PyObject*)Py_TYPE((PyObject*)self);
  int ok = 1;

  BROTLI_CRITICAL_START;
  if (self->healthy == 0) {
    set_brotli_exception(self_type, kCompressUnhealthyError);
    ok = 0;
  }
  if (ok && self->processing != 0) {
    set_brotli_exception(self_type, kCompressConcurrentError);
    ok = 0;
  }
  if (ok) {
    self->processing = 1;
  }
  BROTLI_CRITICAL_END;
  return ok;
}

static void brotli_compressor_leave(PyBrotli_Compressor* self) {
  BROTLI_CRITICAL_START;
  assert(self->processing == 1);
  self->processing = 0;
  BROTLI_CRITICAL_END;
}

/*
   Compress "utility knife" used for process / flush / finish.

   Continues processing until all input is consumed.
   Might return NULL on OOM or internal encoder error.
 */
static PyObject* compress_stream(PyBrotli_Compressor* self,
                                 BrotliEncoderOperation op, uint8_t* input,
                                 size_t input_length) {
  PyObject* self_type = (PyObject*)Py_TYPE((PyObject*)self);
  size_t available_in = input_length;
  const uint8_t* next_in = input;
  Buffer buffer;
  PyObject* ret = NULL;
  int oom = 0;
  BROTLI_BOOL ok = BROTLI_FALSE;
  BrotliEncoderState* enc = self->enc;
  /* Callers must ensure mutually exclusive access to the encoder. */
  assert(self->processing == 1);

  Buffer_Init(&buffer);
  if (Buffer_Grow(&buffer) < 0) {
    oom = 1;
    goto error;
  }

  Py_BEGIN_ALLOW_THREADS;
  while (1) {
    ok = BrotliEncoderCompressStream(enc, op, &available_in, &next_in,
                                     &buffer.avail_out, &buffer.next_out, NULL);
    if (!ok) break;

    if ((available_in > 0) || BrotliEncoderHasMoreOutput(enc)) {
      if (buffer.avail_out == 0) {
        if (Buffer_Grow(&buffer) < 0) {
          oom = 1;
          break;
        }
      }
      continue;
    }
    break;
  }
  Py_END_ALLOW_THREADS;

  if (oom) goto error;
  if (ok) {
    ret = Buffer_Finish(&buffer);
    if (ret == NULL) oom = 1;
  } else { /* Not ok */
    set_brotli_exception(self_type, kCompressError);
  }

error:
  if (oom) {
    PyErr_SetString(PyExc_MemoryError, kOomError);
    assert(ret == NULL);
  }
  Buffer_Cleanup(&buffer);
  if (PyErr_Occurred() != NULL) {
    assert(ret == NULL);
    self->healthy = 0;
    return NULL;
  }
  return ret;
}

static PyObject* brotli_Compressor_process(PyBrotli_Compressor* self,
                                           PyObject* args) {
  PyObject* self_type = (PyObject*)Py_TYPE((PyObject*)self);
  PyObject* ret = NULL;
  PyObject* input_object = NULL;
  Py_buffer input;
  int ok = 1;

  if (!brotli_compressor_enter(self)) return NULL;

  if (!PyArg_ParseTuple(args, "O:process", &input_object)) {
    ok = 0;
  }
  if (ok && !get_data_view(input_object, &input)) {
    ok = 0;
  }
  if (!ok) {
    self->healthy = 0;
    brotli_compressor_leave(self);
    return NULL;
  }

  ret = compress_stream(self, BROTLI_OPERATION_PROCESS, (uint8_t*)input.buf,
                        input.len);
  PyBuffer_Release(&input);
  brotli_compressor_leave(self);

  return ret;
}

static PyObject* brotli_Compressor_flush(PyBrotli_Compressor* self) {
  PyObject* self_type = (PyObject*)Py_TYPE((PyObject*)self);
  PyObject* ret = NULL;

  if (!brotli_compressor_enter(self)) return NULL;
  ret = compress_stream(self, BROTLI_OPERATION_FLUSH, NULL, 0);
  brotli_compressor_leave(self);

  return ret;
}

static PyObject* brotli_Compressor_finish(PyBrotli_Compressor* self) {
  PyObject* self_type = (PyObject*)Py_TYPE((PyObject*)self);
  PyObject* ret = NULL;

  if (!brotli_compressor_enter(self)) return NULL;
  ret = compress_stream(self, BROTLI_OPERATION_FINISH, NULL, 0);
  brotli_compressor_leave(self);

  if (ret != NULL) {
    assert(BrotliEncoderIsFinished(self->enc));
  }
  return ret;
}

/* --- Decompressor --- */

typedef struct {
  PyObject_HEAD BrotliDecoderState* dec;
  uint8_t* unconsumed_data;
  size_t unconsumed_data_length;
  int healthy;
  int processing;
} PyBrotli_Decompressor;

static PyObject* brotli_Decompressor_new(PyTypeObject* type, PyObject* args,
                                         PyObject* keywds) {
  /* `tp_itemsize` is 0, so `nitems` could be 0. */
  PyBrotli_Decompressor* self = (PyBrotli_Decompressor*)type->tp_alloc(type, 0);
  PyObject* self_type = (PyObject*)type;

  if (self == NULL) return NULL;
  self->healthy = 0;
  self->processing = 0;

  self->dec = BrotliDecoderCreateInstance(0, 0, 0);
  if (self->dec == NULL) {
    set_brotli_exception(self_type, kDecompressCreateError);
    Py_TYPE(self)->tp_free((PyObject*)self);
    return NULL;
  }

  self->unconsumed_data = NULL;
  self->unconsumed_data_length = 0;
  self->healthy = 1;

  return (PyObject*)self;
}

static int brotli_Decompressor_init(PyBrotli_Decompressor* self, PyObject* args,
                                    PyObject* keywds) {
  static const char* kwlist[] = {NULL};

  int ok = PyArg_ParseTupleAndKeywords(args, keywds, "|:Decompressor",
                                       (char**)kwlist);

  assert(self->healthy);

  if (!ok) {
    self->healthy = 0;
    return -1;
  }

  return 0;
}

static int brotli_decompressor_enter(PyBrotli_Decompressor* self) {
  PyObject* self_type = (PyObject*)Py_TYPE((PyObject*)self);
  int ok = 1;

  BROTLI_CRITICAL_START;
  if (self->healthy == 0) {
    set_brotli_exception(self_type, kDecompressUnhealthyError);
    ok = 0;
  }
  if (ok && self->processing != 0) {
    set_brotli_exception(self_type, kDecompressConcurrentError);
    ok = 0;
  }
  if (ok) {
    self->processing = 1;
  }
  BROTLI_CRITICAL_END;
  return ok;
}

static void brotli_decompressor_leave(PyBrotli_Decompressor* self) {
  BROTLI_CRITICAL_START;
  assert(self->processing == 1);
  self->processing = 0;
  BROTLI_CRITICAL_END;
}

static void brotli_Decompressor_dealloc(PyBrotli_Decompressor* self) {
  if (self->dec) BrotliDecoderDestroyInstance(self->dec);
  if (self->unconsumed_data) {
    free(self->unconsumed_data);
    self->unconsumed_data = NULL;
  }
  Py_TYPE(self)->tp_free((PyObject*)self);
}

static PyObject* brotli_Decompressor_process(PyBrotli_Decompressor* self,
                                             PyObject* args, PyObject* keywds) {
  static const char* kwlist[] = {"", "output_buffer_limit", NULL};

  PyObject* self_type = (PyObject*)Py_TYPE((PyObject*)self);
  PyObject* ret = NULL;
  PyObject* input_object = NULL;
  Py_buffer input;
  Py_ssize_t output_buffer_limit = PY_SSIZE_T_MAX;
  const uint8_t* next_in = NULL;
  size_t avail_in = 0;
  BrotliDecoderResult result = BROTLI_DECODER_RESULT_ERROR;
  Buffer buffer;
  uint8_t* new_tail = NULL;
  size_t new_tail_length = 0;
  int oom = 0;
  int ok = 1;

  if (!brotli_decompressor_enter(self)) return NULL;

  if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|n:process", (char**)kwlist,
                                   &input_object, &output_buffer_limit)) {
    ok = 0;
  }
  if (ok && !get_data_view(input_object, &input)) {
    ok = 0;
  }
  if (!ok) {
    self->healthy = 0;
    brotli_decompressor_leave(self);
    return NULL;
  }

  Buffer_Init(&buffer);

  if (self->unconsumed_data_length > 0) {
    if (input.len > 0) {
      set_brotli_exception(self_type, kDecompressSinkError);
      goto finally;
    }
    next_in = self->unconsumed_data;
    avail_in = self->unconsumed_data_length;
  } else {
    next_in = (uint8_t*)input.buf;
    avail_in = input.len;
  }

  /* While not guaranteed, we expect that some output will be produced. */
  if (Buffer_Grow(&buffer) < 0) {
    oom = 1;
    goto finally;
  }

  Py_BEGIN_ALLOW_THREADS;
  while (1) {
    result = BrotliDecoderDecompressStream(self->dec, &avail_in, &next_in,
                                           &buffer.avail_out, &buffer.next_out,
                                           NULL);

    if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
      assert(buffer.avail_out == 0);
      /* All allocated is used -> reached the output length limit. */
      if (buffer.total_allocated >= (uint64_t)output_buffer_limit) break;
      if (Buffer_Grow(&buffer) < 0) {
        oom = 1;
        break;
      }
      continue;
    }
    break;
  }
  Py_END_ALLOW_THREADS;

  if (oom) {
    goto finally;
  } else if (result == BROTLI_DECODER_RESULT_ERROR) {
    set_brotli_exception(self_type, kDecompressError);
    goto finally;
  }

  /* Here result is either SUCCESS / NEEDS_MORE_INPUT / NEEDS_MORE_OUTPUT (if
     `output_buffer_limit` was reached). */

  if (avail_in > 0) {
    new_tail = malloc(avail_in);
    if (new_tail == NULL) {
      oom = 1;
      goto finally;
    }
    memcpy(new_tail, next_in, avail_in);
    new_tail_length = avail_in;
  }

  if ((result == BROTLI_DECODER_RESULT_SUCCESS) && (avail_in > 0)) {
    /* TODO(eustas): Add API to ignore / fetch unused "tail"? */
    set_brotli_exception(self_type, kDecompressError);
    goto finally;
  }

  ret = Buffer_Finish(&buffer);
  if (ret == NULL) oom = 1;

finally:
  if (oom) {
    PyErr_SetString(PyExc_MemoryError, kOomError);
    assert(ret == NULL);
  }
  PyBuffer_Release(&input);
  Buffer_Cleanup(&buffer);
  if (self->unconsumed_data) {
    free(self->unconsumed_data);
    self->unconsumed_data = NULL;
  }
  self->unconsumed_data = new_tail;
  self->unconsumed_data_length = new_tail_length;
  if (PyErr_Occurred() != NULL) {
    assert(ret == NULL);
    self->healthy = 0;
  }
  brotli_decompressor_leave(self);

  return ret;
}

static PyObject* brotli_Decompressor_is_finished(PyBrotli_Decompressor* self) {
  int result;
  if (!brotli_decompressor_enter(self)) return NULL;
  result = BrotliDecoderIsFinished(self->dec);
  brotli_decompressor_leave(self);
  if (result) {
    Py_RETURN_TRUE;
  } else {
    Py_RETURN_FALSE;
  }
}

static PyObject* brotli_Decompressor_can_accept_more_data(
    PyBrotli_Decompressor* self) {
  int result;
  if (!brotli_decompressor_enter(self)) return NULL;
  result = (self->unconsumed_data_length > 0);
  brotli_decompressor_leave(self);
  if (result) {
    Py_RETURN_FALSE;
  } else {
    Py_RETURN_TRUE;
  }
}

/* --- Module functions --- */

static PyObject* brotli_decompress(PyObject* m, PyObject* args,
                                   PyObject* keywds) {
  static const char* kwlist[] = {"string", NULL};

  BrotliDecoderState* state = NULL;
  BrotliDecoderResult result = BROTLI_DECODER_RESULT_ERROR;
  const uint8_t* next_in = NULL;
  size_t available_in = 0;
  Buffer buffer;
  PyObject* ret = NULL;
  PyObject* input_object = NULL;
  Py_buffer input;
  int oom = 0;

  if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|:decompress",
                                   (char**)kwlist, &input_object)) {
    return NULL;
  }
  if (!get_data_view(input_object, &input)) {
    return NULL;
  }

  Buffer_Init(&buffer);

  next_in = (uint8_t*)input.buf;
  available_in = input.len;

  state = BrotliDecoderCreateInstance(0, 0, 0);
  if (state == NULL) {
    oom = 1;
    goto finally;
  }

  if (Buffer_Grow(&buffer) < 0) {
    oom = 1;
    goto finally;
  }

  Py_BEGIN_ALLOW_THREADS;
  while (1) {
    result = BrotliDecoderDecompressStream(
        state, &available_in, &next_in, &buffer.avail_out, &buffer.next_out, 0);
    if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
      assert(buffer.avail_out == 0);
      if (Buffer_Grow(&buffer) < 0) {
        oom = 1;
        break;
      }
      continue;
    }
    break;
  }
  Py_END_ALLOW_THREADS;

  if (oom) {
    goto finally;
  } else if (result != BROTLI_DECODER_RESULT_SUCCESS || available_in > 0) {
    set_brotli_exception_from_module(m, kDecompressError);
    goto finally;
  }

  ret = Buffer_Finish(&buffer);
  if (ret == NULL) oom = 1;

finally:
  if (oom) PyErr_SetString(PyExc_MemoryError, kOomError);
  PyBuffer_Release(&input);
  Buffer_Cleanup(&buffer);
  if (state) BrotliDecoderDestroyInstance(state);
  return ret;
}

/* Module definition */

static PyMethodDef brotli_Compressor_methods[] = {
    {"process", (PyCFunction)brotli_Compressor_process, METH_VARARGS,
     brotli_Compressor_process_doc},
    {"flush", (PyCFunction)brotli_Compressor_flush, METH_NOARGS,
     brotli_Compressor_flush_doc},
    {"finish", (PyCFunction)brotli_Compressor_finish, METH_NOARGS,
     brotli_Compressor_finish_doc},
    {NULL} /* Sentinel */
};

static PyType_Slot brotli_Compressor_slots[] = {
    {Py_tp_dealloc, (destructor)brotli_Compressor_dealloc},
    {Py_tp_doc, (void*)brotli_Compressor_doc},
    {Py_tp_methods, brotli_Compressor_methods},
    {Py_tp_init, (initproc)brotli_Compressor_init},
    {Py_tp_new, brotli_Compressor_new},
    {0, 0},
};

static PyType_Spec brotli_Compressor_spec = {
    "brotli.Compressor", sizeof(PyBrotli_Compressor), 0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, brotli_Compressor_slots};

static PyMethodDef brotli_Decompressor_methods[] = {
    {"process", (PyCFunction)brotli_Decompressor_process,
     METH_VARARGS | METH_KEYWORDS, brotli_Decompressor_process_doc},
    {"is_finished", (PyCFunction)brotli_Decompressor_is_finished, METH_NOARGS,
     brotli_Decompressor_is_finished_doc},
    {"can_accept_more_data",
     (PyCFunction)brotli_Decompressor_can_accept_more_data, METH_NOARGS,
     brotli_Decompressor_can_accept_more_data_doc},
    {NULL} /* Sentinel */
};

static PyType_Slot brotli_Decompressor_slots[] = {
    {Py_tp_dealloc, (destructor)brotli_Decompressor_dealloc},
    {Py_tp_doc, (void*)brotli_Decompressor_doc},
    {Py_tp_methods, brotli_Decompressor_methods},
    {Py_tp_init, (initproc)brotli_Decompressor_init},
    {Py_tp_new, brotli_Decompressor_new},
    {0, 0},
};

static PyType_Spec brotli_Decompressor_spec = {
    "brotli.Decompressor", sizeof(PyBrotli_Decompressor), 0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, brotli_Decompressor_slots};

/* Emulates PyModule_AddObject */
static int RegisterObject(PyObject* mod, const char* name, PyObject* value) {
  assert(value != NULL);
  int ret = PyModule_AddObjectRef(mod, name, value);
  /* Emulates PyModule_AddObject, i.e. decrements the reference count on
     success. */
  if (ret == 0) Py_DECREF(value);
  return ret;
}

static int brotli_init_mod(PyObject* m) {
  PyObject* error_type = NULL;
  PyObject* compressor_type = NULL;
  PyObject* decompressor_type = NULL;
  assert(m != NULL);

  error_type = PyErr_NewExceptionWithDoc((char*)"brotli.error",
                                         brotli_error_doc, NULL, NULL);
  if (error_type == NULL) goto error;

  if (RegisterObject(m, kErrorAttr, error_type) < 0) goto error;
  error_type = NULL;

  compressor_type = PyType_FromSpec(&brotli_Compressor_spec);
  decompressor_type = PyType_FromSpec(&brotli_Decompressor_spec);
  if (compressor_type == NULL) goto error;
  if (PyType_Ready((PyTypeObject*)compressor_type) < 0) goto error;
  if (PyObject_SetAttrString(compressor_type, kModuleAttr, m) < 0) goto error;
  if (RegisterObject(m, "Compressor", compressor_type) < 0) goto error;
  compressor_type = NULL;

  if (decompressor_type == NULL) goto error;
  if (PyType_Ready((PyTypeObject*)decompressor_type) < 0) goto error;
  if (PyObject_SetAttrString(decompressor_type, kModuleAttr, m) < 0) goto error;
  if (RegisterObject(m, "Decompressor", decompressor_type) < 0) goto error;
  decompressor_type = NULL;

  PyModule_AddIntConstant(m, "MODE_GENERIC", (int)BROTLI_MODE_GENERIC);
  PyModule_AddIntConstant(m, "MODE_TEXT", (int)BROTLI_MODE_TEXT);
  PyModule_AddIntConstant(m, "MODE_FONT", (int)BROTLI_MODE_FONT);

  char version[16]; /* 3 + 1 + 4 + 1 + 4 + 1 == 14 */
  uint32_t decoderVersion = BrotliDecoderVersion();
  snprintf(version, sizeof(version), "%d.%d.%d", decoderVersion >> 24,
           (decoderVersion >> 12) & 0xFFF, decoderVersion & 0xFFF);
  PyModule_AddStringConstant(m, "__version__", version);

  return 0;

error:
  if (error_type != NULL) {
    Py_DECREF(error_type);
    error_type = NULL;
  }
  if (compressor_type != NULL) {
    Py_DECREF(compressor_type);
    compressor_type = NULL;
  }
  if (decompressor_type != NULL) {
    Py_DECREF(decompressor_type);
    decompressor_type = NULL;
  }
  return -1;
}

static PyMethodDef brotli_methods[] = {
    {"decompress", (PyCFunction)brotli_decompress, METH_VARARGS | METH_KEYWORDS,
     brotli_decompress__doc__},
    {NULL, NULL, 0, NULL}};

static PyModuleDef_Slot brotli_mod_slots[] = {
    {Py_mod_exec, brotli_init_mod},
#ifdef Py_GIL_DISABLED
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
#elif (PY_MAJOR_VERSION > 3) || (PY_MINOR_VERSION >= 12)
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
#endif
    {0, NULL}};

static struct PyModuleDef brotli_module = {
    PyModuleDef_HEAD_INIT,
    "_brotli",        /* m_name */
    brotli_doc,       /* m_doc */
    0,                /* m_size */
    brotli_methods,   /* m_methods */
    brotli_mod_slots, /* m_slots */
    NULL,             /* m_traverse */
    NULL,             /* m_clear */
    NULL              /* m_free */
};

PyMODINIT_FUNC PyInit__brotli(void) { return PyModuleDef_Init(&brotli_module); }
