/* Low level interface to the Zstandard algorthm & the zstd library. */

#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "Python.h"

#include "_zstdmodule.h"
#include "zstddict.h"

#include <zstd.h>                 // ZSTD_*()
#include <zdict.h>                // ZDICT_*()

/*[clinic input]
module _zstd

[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b5f5587aac15c14]*/
#include "clinic/_zstdmodule.c.h"


/* Format error message and set ZstdError. */
void
set_zstd_error(const _zstd_state* const state,
               error_type type, size_t zstd_ret)
{
    char *msg;
    assert(ZSTD_isError(zstd_ret));

    switch (type)
    {
    case ERR_DECOMPRESS:
        msg = "Unable to decompress Zstandard data: %s";
        break;
    case ERR_COMPRESS:
        msg = "Unable to compress Zstandard data: %s";
        break;

    case ERR_LOAD_D_DICT:
        msg = "Unable to load Zstandard dictionary or prefix for decompression: %s";
        break;
    case ERR_LOAD_C_DICT:
        msg = "Unable to load Zstandard dictionary or prefix for compression: %s";
        break;

    case ERR_GET_C_BOUNDS:
        msg = "Unable to get zstd compression parameter bounds: %s";
        break;
    case ERR_GET_D_BOUNDS:
        msg = "Unable to get zstd decompression parameter bounds: %s";
        break;
    case ERR_SET_C_LEVEL:
        msg = "Unable to set zstd compression level: %s";
        break;

    case ERR_TRAIN_DICT:
        msg = "Unable to train the Zstandard dictionary: %s";
        break;
    case ERR_FINALIZE_DICT:
        msg = "Unable to finalize the Zstandard dictionary: %s";
        break;

    default:
        Py_UNREACHABLE();
    }
    PyErr_Format(state->ZstdError, msg, ZSTD_getErrorName(zstd_ret));
}

typedef struct {
    int parameter;
    char parameter_name[32];
} ParameterInfo;

static const ParameterInfo cp_list[] = {
    {ZSTD_c_compressionLevel, "compression_level"},
    {ZSTD_c_windowLog,        "window_log"},
    {ZSTD_c_hashLog,          "hash_log"},
    {ZSTD_c_chainLog,         "chain_log"},
    {ZSTD_c_searchLog,        "search_log"},
    {ZSTD_c_minMatch,         "min_match"},
    {ZSTD_c_targetLength,     "target_length"},
    {ZSTD_c_strategy,         "strategy"},

    {ZSTD_c_enableLongDistanceMatching, "enable_long_distance_matching"},
    {ZSTD_c_ldmHashLog,       "ldm_hash_log"},
    {ZSTD_c_ldmMinMatch,      "ldm_min_match"},
    {ZSTD_c_ldmBucketSizeLog, "ldm_bucket_size_log"},
    {ZSTD_c_ldmHashRateLog,   "ldm_hash_rate_log"},

    {ZSTD_c_contentSizeFlag,  "content_size_flag"},
    {ZSTD_c_checksumFlag,     "checksum_flag"},
    {ZSTD_c_dictIDFlag,       "dict_id_flag"},

    {ZSTD_c_nbWorkers,        "nb_workers"},
    {ZSTD_c_jobSize,          "job_size"},
    {ZSTD_c_overlapLog,       "overlap_log"}
};

static const ParameterInfo dp_list[] = {
    {ZSTD_d_windowLogMax, "window_log_max"}
};

void
set_parameter_error(const _zstd_state* const state, int is_compress,
                    int key_v, int value_v)
{
    ParameterInfo const *list;
    int list_size;
    char const *name;
    char *type;
    ZSTD_bounds bounds;
    int i;
    char pos_msg[128];

    if (is_compress) {
        list = cp_list;
        list_size = Py_ARRAY_LENGTH(cp_list);
        type = "compression";
    }
    else {
        list = dp_list;
        list_size = Py_ARRAY_LENGTH(dp_list);
        type = "decompression";
    }

    /* Find parameter's name */
    name = NULL;
    for (i = 0; i < list_size; i++) {
        if (key_v == (list+i)->parameter) {
            name = (list+i)->parameter_name;
            break;
        }
    }

    /* Unknown parameter */
    if (name == NULL) {
        PyOS_snprintf(pos_msg, sizeof(pos_msg),
                      "unknown parameter (key %d)", key_v);
        name = pos_msg;
    }

    /* Get parameter bounds */
    if (is_compress) {
        bounds = ZSTD_cParam_getBounds(key_v);
    }
    else {
        bounds = ZSTD_dParam_getBounds(key_v);
    }
    if (ZSTD_isError(bounds.error)) {
        PyErr_Format(state->ZstdError,
                     "Invalid zstd %s parameter \"%s\".",
                     type, name);
        return;
    }

    /* Error message */
    PyErr_Format(state->ZstdError,
                 "Error when setting zstd %s parameter \"%s\", it "
                 "should %d <= value <= %d, provided value is %d. "
                 "(%d-bit build)",
                 type, name,
                 bounds.lowerBound, bounds.upperBound, value_v,
                 8*(int)sizeof(Py_ssize_t));
}

static inline _zstd_state*
get_zstd_state(PyObject *module)
{
    void *state = PyModule_GetState(module);
    assert(state != NULL);
    return (_zstd_state *)state;
}

static Py_ssize_t
calculate_samples_stats(PyBytesObject *samples_bytes, PyObject *samples_sizes,
                    size_t **chunk_sizes)
{
    Py_ssize_t chunks_number;
    Py_ssize_t sizes_sum;
    Py_ssize_t i;

    chunks_number = Py_SIZE(samples_sizes);
    if ((size_t) chunks_number > UINT32_MAX) {
        PyErr_Format(PyExc_ValueError,
                        "The number of samples should be <= %u.", UINT32_MAX);
        return -1;
    }

    /* Prepare chunk_sizes */
    *chunk_sizes = PyMem_New(size_t, chunks_number);
    if (*chunk_sizes == NULL) {
        PyErr_NoMemory();
        return -1;
    }

    sizes_sum = 0;
    for (i = 0; i < chunks_number; i++) {
        PyObject *size = PyTuple_GetItem(samples_sizes, i);
        (*chunk_sizes)[i] = PyLong_AsSize_t(size);
        if ((*chunk_sizes)[i] == (size_t)-1 && PyErr_Occurred()) {
            PyErr_Format(PyExc_ValueError,
                            "Items in samples_sizes should be an int "
                            "object, with a value between 0 and %u.", SIZE_MAX);
            return -1;
        }
        sizes_sum += (*chunk_sizes)[i];
    }

    if (sizes_sum != Py_SIZE(samples_bytes)) {
        PyErr_SetString(PyExc_ValueError,
                        "The samples size tuple doesn't match the concatenation's size.");
        return -1;
    }
    return chunks_number;
}


/*[clinic input]
_zstd.train_dict

    samples_bytes: PyBytesObject
        Concatenation of samples.
    samples_sizes: object(subclass_of='&PyTuple_Type')
        Tuple of samples' sizes.
    dict_size: Py_ssize_t
        The size of the dictionary.
    /

Train a Zstandard dictionary on sample data.
[clinic start generated code]*/

static PyObject *
_zstd_train_dict_impl(PyObject *module, PyBytesObject *samples_bytes,
                      PyObject *samples_sizes, Py_ssize_t dict_size)
/*[clinic end generated code: output=8e87fe43935e8f77 input=d20dedb21c72cb62]*/
{
    PyObject *dst_dict_bytes = NULL;
    size_t *chunk_sizes = NULL;
    Py_ssize_t chunks_number;
    size_t zstd_ret;

    /* Check arguments */
    if (dict_size <= 0) {
        PyErr_SetString(PyExc_ValueError, "dict_size argument should be positive number.");
        return NULL;
    }

    /* Check that the samples are valid and get their sizes */
    chunks_number = calculate_samples_stats(samples_bytes, samples_sizes,
                                            &chunk_sizes);
    if (chunks_number < 0)
    {
        goto error;
    }

    /* Allocate dict buffer */
    dst_dict_bytes = PyBytes_FromStringAndSize(NULL, dict_size);
    if (dst_dict_bytes == NULL) {
        goto error;
    }

    /* Train the dictionary */
    char *dst_dict_buffer = PyBytes_AS_STRING(dst_dict_bytes);
    char *samples_buffer = PyBytes_AS_STRING(samples_bytes);
    Py_BEGIN_ALLOW_THREADS
    zstd_ret = ZDICT_trainFromBuffer(dst_dict_buffer, dict_size,
                                     samples_buffer,
                                     chunk_sizes, (uint32_t)chunks_number);
    Py_END_ALLOW_THREADS

    /* Check Zstandard dict error */
    if (ZDICT_isError(zstd_ret)) {
        _zstd_state* const mod_state = get_zstd_state(module);
        set_zstd_error(mod_state, ERR_TRAIN_DICT, zstd_ret);
        goto error;
    }

    /* Resize dict_buffer */
    if (_PyBytes_Resize(&dst_dict_bytes, zstd_ret) < 0) {
        goto error;
    }

    goto success;

error:
    Py_CLEAR(dst_dict_bytes);

success:
    PyMem_Free(chunk_sizes);
    return dst_dict_bytes;
}

/*[clinic input]
_zstd.finalize_dict

    custom_dict_bytes: PyBytesObject
        Custom dictionary content.
    samples_bytes: PyBytesObject
        Concatenation of samples.
    samples_sizes: object(subclass_of='&PyTuple_Type')
        Tuple of samples' sizes.
    dict_size: Py_ssize_t
        The size of the dictionary.
    compression_level: int
        Optimize for a specific Zstandard compression level, 0 means default.
    /

Finalize a Zstandard dictionary.
[clinic start generated code]*/

static PyObject *
_zstd_finalize_dict_impl(PyObject *module, PyBytesObject *custom_dict_bytes,
                         PyBytesObject *samples_bytes,
                         PyObject *samples_sizes, Py_ssize_t dict_size,
                         int compression_level)
/*[clinic end generated code: output=f91821ba5ae85bda input=3c7e2480aa08fb56]*/
{
    Py_ssize_t chunks_number;
    size_t *chunk_sizes = NULL;
    PyObject *dst_dict_bytes = NULL;
    size_t zstd_ret;
    ZDICT_params_t params;

    /* Check arguments */
    if (dict_size <= 0) {
        PyErr_SetString(PyExc_ValueError, "dict_size argument should be positive number.");
        return NULL;
    }

    /* Check that the samples are valid and get their sizes */
    chunks_number = calculate_samples_stats(samples_bytes, samples_sizes,
                                            &chunk_sizes);
    if (chunks_number < 0)
    {
        goto error;
    }

    /* Allocate dict buffer */
    dst_dict_bytes = PyBytes_FromStringAndSize(NULL, dict_size);
    if (dst_dict_bytes == NULL) {
        goto error;
    }

    /* Parameters */

    /* Optimize for a specific Zstandard compression level, 0 means default. */
    params.compressionLevel = compression_level;
    /* Write log to stderr, 0 = none. */
    params.notificationLevel = 0;
    /* Force dictID value, 0 means auto mode (32-bits random value). */
    params.dictID = 0;

    /* Finalize the dictionary */
    Py_BEGIN_ALLOW_THREADS
    zstd_ret = ZDICT_finalizeDictionary(
                        PyBytes_AS_STRING(dst_dict_bytes), dict_size,
                        PyBytes_AS_STRING(custom_dict_bytes), Py_SIZE(custom_dict_bytes),
                        PyBytes_AS_STRING(samples_bytes), chunk_sizes,
                        (uint32_t)chunks_number, params);
    Py_END_ALLOW_THREADS

    /* Check Zstandard dict error */
    if (ZDICT_isError(zstd_ret)) {
        _zstd_state* const mod_state = get_zstd_state(module);
        set_zstd_error(mod_state, ERR_FINALIZE_DICT, zstd_ret);
        goto error;
    }

    /* Resize dict_buffer */
    if (_PyBytes_Resize(&dst_dict_bytes, zstd_ret) < 0) {
        goto error;
    }

    goto success;

error:
    Py_CLEAR(dst_dict_bytes);

success:
    PyMem_Free(chunk_sizes);
    return dst_dict_bytes;
}


/*[clinic input]
_zstd.get_param_bounds

    parameter: int
        The parameter to get bounds.
    is_compress: bool
        True for CompressionParameter, False for DecompressionParameter.

Get CompressionParameter/DecompressionParameter bounds.
[clinic start generated code]*/

static PyObject *
_zstd_get_param_bounds_impl(PyObject *module, int parameter, int is_compress)
/*[clinic end generated code: output=4acf5a876f0620ca input=45742ef0a3531b65]*/
{
    ZSTD_bounds bound;
    if (is_compress) {
        bound = ZSTD_cParam_getBounds(parameter);
        if (ZSTD_isError(bound.error)) {
            _zstd_state* const mod_state = get_zstd_state(module);
            set_zstd_error(mod_state, ERR_GET_C_BOUNDS, bound.error);
            return NULL;
        }
    }
    else {
        bound = ZSTD_dParam_getBounds(parameter);
        if (ZSTD_isError(bound.error)) {
            _zstd_state* const mod_state = get_zstd_state(module);
            set_zstd_error(mod_state, ERR_GET_D_BOUNDS, bound.error);
            return NULL;
        }
    }

    return Py_BuildValue("ii", bound.lowerBound, bound.upperBound);
}

/*[clinic input]
_zstd.get_frame_size

    frame_buffer: Py_buffer
        A bytes-like object, it should start from the beginning of a frame,
        and contains at least one complete frame.

Get the size of a Zstandard frame, including the header and optional checksum.
[clinic start generated code]*/

static PyObject *
_zstd_get_frame_size_impl(PyObject *module, Py_buffer *frame_buffer)
/*[clinic end generated code: output=a7384c2f8780f442 input=3b9f73f8c8129d38]*/
{
    size_t frame_size;

    frame_size = ZSTD_findFrameCompressedSize(frame_buffer->buf, frame_buffer->len);
    if (ZSTD_isError(frame_size)) {
        _zstd_state* const mod_state = get_zstd_state(module);
        PyErr_Format(mod_state->ZstdError,
            "Error when finding the compressed size of a Zstandard frame. "
            "Ensure the frame_buffer argument starts from the "
            "beginning of a frame, and its length is not less than this "
            "complete frame. Zstd error message: %s.",
            ZSTD_getErrorName(frame_size));
        return NULL;
    }

    return PyLong_FromSize_t(frame_size);
}

/*[clinic input]
_zstd.get_frame_info

    frame_buffer: Py_buffer
        A bytes-like object, containing the header of a Zstandard frame.

Get Zstandard frame infomation from a frame header.
[clinic start generated code]*/

static PyObject *
_zstd_get_frame_info_impl(PyObject *module, Py_buffer *frame_buffer)
/*[clinic end generated code: output=56e033cf48001929 input=94b240583ae22ca5]*/
{
    uint64_t decompressed_size;
    uint32_t dict_id;

    /* ZSTD_getFrameContentSize */
    decompressed_size = ZSTD_getFrameContentSize(frame_buffer->buf,
                                                 frame_buffer->len);

    /* #define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
       #define ZSTD_CONTENTSIZE_ERROR   (0ULL - 2) */
    if (decompressed_size == ZSTD_CONTENTSIZE_ERROR) {
        _zstd_state* const mod_state = get_zstd_state(module);
        PyErr_SetString(mod_state->ZstdError,
            "Error when getting information from the header of "
            "a Zstandard frame. Ensure the frame_buffer argument "
            "starts from the beginning of a frame, and its length "
            "is not less than the frame header (6~18 bytes).");
        return NULL;
    }

    /* ZSTD_getDictID_fromFrame */
    dict_id = ZSTD_getDictID_fromFrame(frame_buffer->buf, frame_buffer->len);

    /* Build tuple */
    if (decompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
        return Py_BuildValue("OI", Py_None, dict_id);
    }
    return Py_BuildValue("KI", decompressed_size, dict_id);
}

/*[clinic input]
_zstd.set_parameter_types

    c_parameter_type: object(subclass_of='&PyType_Type')
        CompressionParameter IntEnum type object
    d_parameter_type: object(subclass_of='&PyType_Type')
        DecompressionParameter IntEnum type object

Set CompressionParameter and DecompressionParameter types for validity check.
[clinic start generated code]*/

static PyObject *
_zstd_set_parameter_types_impl(PyObject *module, PyObject *c_parameter_type,
                               PyObject *d_parameter_type)
/*[clinic end generated code: output=f3313b1294f19502 input=75d7a953580fae5f]*/
{
    _zstd_state* const mod_state = get_zstd_state(module);

    if (!PyType_Check(c_parameter_type) || !PyType_Check(d_parameter_type)) {
        PyErr_SetString(PyExc_ValueError,
                        "The two arguments should be CompressionParameter and "
                        "DecompressionParameter types.");
        return NULL;
    }

    Py_XDECREF(mod_state->CParameter_type);
    Py_INCREF(c_parameter_type);
    mod_state->CParameter_type = (PyTypeObject*)c_parameter_type;

    Py_XDECREF(mod_state->DParameter_type);
    Py_INCREF(d_parameter_type);
    mod_state->DParameter_type = (PyTypeObject*)d_parameter_type;

    Py_RETURN_NONE;
}

static PyMethodDef _zstd_methods[] = {
    _ZSTD_TRAIN_DICT_METHODDEF
    _ZSTD_FINALIZE_DICT_METHODDEF
    _ZSTD_GET_PARAM_BOUNDS_METHODDEF
    _ZSTD_GET_FRAME_SIZE_METHODDEF
    _ZSTD_GET_FRAME_INFO_METHODDEF
    _ZSTD_SET_PARAMETER_TYPES_METHODDEF
    {NULL, NULL}
};

static int
_zstd_exec(PyObject *m)
{
#define ADD_TYPE(TYPE, SPEC)                                                 \
do {                                                                         \
    TYPE = (PyTypeObject *)PyType_FromModuleAndSpec(m, &(SPEC), NULL);       \
    if (TYPE == NULL) {                                                      \
        return -1;                                                           \
    }                                                                        \
    if (PyModule_AddType(m, TYPE) < 0) {                                     \
        return -1;                                                           \
    }                                                                        \
} while (0)

#define ADD_INT_MACRO(MACRO)                                                 \
    if (PyModule_AddIntConstant((m), #MACRO, (MACRO)) < 0) {                 \
        return -1;                                                           \
    }

#define ADD_INT_CONST_TO_TYPE(TYPE, NAME, VALUE)                             \
do {                                                                         \
    PyObject *v = PyLong_FromLong((VALUE));                                  \
    if (v == NULL || PyObject_SetAttrString((PyObject *)(TYPE),              \
                                            (NAME), v) < 0) {                \
        Py_XDECREF(v);                                                       \
        return -1;                                                           \
    }                                                                        \
    Py_DECREF(v);                                                            \
} while (0)

    _zstd_state* const mod_state = get_zstd_state(m);

    /* Reusable objects & variables */
    mod_state->CParameter_type = NULL;
    mod_state->DParameter_type = NULL;

    /* Create and add heap types */
    ADD_TYPE(mod_state->ZstdDict_type, zstd_dict_type_spec);
    ADD_TYPE(mod_state->ZstdCompressor_type, zstd_compressor_type_spec);
    ADD_TYPE(mod_state->ZstdDecompressor_type, zstd_decompressor_type_spec);
    mod_state->ZstdError = PyErr_NewExceptionWithDoc(
        "compression.zstd.ZstdError",
        "An error occurred in the zstd library.",
        NULL, NULL);
    if (mod_state->ZstdError == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, (PyTypeObject *)mod_state->ZstdError) < 0) {
        Py_DECREF(mod_state->ZstdError);
        return -1;
    }

    /* Add constants */
    if (PyModule_AddIntConstant(m, "zstd_version_number",
                                ZSTD_versionNumber()) < 0) {
        return -1;
    }

    if (PyModule_AddStringConstant(m, "zstd_version",
                                   ZSTD_versionString()) < 0) {
        return -1;
    }

#if ZSTD_VERSION_NUMBER >= 10500
    if (PyModule_AddIntConstant(m, "ZSTD_CLEVEL_DEFAULT",
                                ZSTD_defaultCLevel()) < 0) {
        return -1;
    }
#else
    ADD_INT_MACRO(ZSTD_CLEVEL_DEFAULT);
#endif

    if (PyModule_Add(m, "ZSTD_DStreamOutSize",
                     PyLong_FromSize_t(ZSTD_DStreamOutSize())) < 0) {
        return -1;
    }

    /* Add zstd compression parameters. All should also be in cp_list. */
    ADD_INT_MACRO(ZSTD_c_compressionLevel);
    ADD_INT_MACRO(ZSTD_c_windowLog);
    ADD_INT_MACRO(ZSTD_c_hashLog);
    ADD_INT_MACRO(ZSTD_c_chainLog);
    ADD_INT_MACRO(ZSTD_c_searchLog);
    ADD_INT_MACRO(ZSTD_c_minMatch);
    ADD_INT_MACRO(ZSTD_c_targetLength);
    ADD_INT_MACRO(ZSTD_c_strategy);

    ADD_INT_MACRO(ZSTD_c_enableLongDistanceMatching);
    ADD_INT_MACRO(ZSTD_c_ldmHashLog);
    ADD_INT_MACRO(ZSTD_c_ldmMinMatch);
    ADD_INT_MACRO(ZSTD_c_ldmBucketSizeLog);
    ADD_INT_MACRO(ZSTD_c_ldmHashRateLog);

    ADD_INT_MACRO(ZSTD_c_contentSizeFlag);
    ADD_INT_MACRO(ZSTD_c_checksumFlag);
    ADD_INT_MACRO(ZSTD_c_dictIDFlag);

    ADD_INT_MACRO(ZSTD_c_nbWorkers);
    ADD_INT_MACRO(ZSTD_c_jobSize);
    ADD_INT_MACRO(ZSTD_c_overlapLog);

    /* Add zstd decompression parameters. All should also be in dp_list. */
    ADD_INT_MACRO(ZSTD_d_windowLogMax);

    /* Add ZSTD_strategy enum members */
    ADD_INT_MACRO(ZSTD_fast);
    ADD_INT_MACRO(ZSTD_dfast);
    ADD_INT_MACRO(ZSTD_greedy);
    ADD_INT_MACRO(ZSTD_lazy);
    ADD_INT_MACRO(ZSTD_lazy2);
    ADD_INT_MACRO(ZSTD_btlazy2);
    ADD_INT_MACRO(ZSTD_btopt);
    ADD_INT_MACRO(ZSTD_btultra);
    ADD_INT_MACRO(ZSTD_btultra2);

    /* Add ZSTD_EndDirective enum members to ZstdCompressor */
    ADD_INT_CONST_TO_TYPE(mod_state->ZstdCompressor_type,
                          "CONTINUE", ZSTD_e_continue);
    ADD_INT_CONST_TO_TYPE(mod_state->ZstdCompressor_type,
                          "FLUSH_BLOCK", ZSTD_e_flush);
    ADD_INT_CONST_TO_TYPE(mod_state->ZstdCompressor_type,
                          "FLUSH_FRAME", ZSTD_e_end);

    /* Make ZstdCompressor immutable (set Py_TPFLAGS_IMMUTABLETYPE) */
    PyType_Freeze(mod_state->ZstdCompressor_type);

#undef ADD_TYPE
#undef ADD_INT_MACRO
#undef ADD_ZSTD_COMPRESSOR_INT_CONST

    return 0;
}

static int
_zstd_traverse(PyObject *module, visitproc visit, void *arg)
{
    _zstd_state* const mod_state = get_zstd_state(module);

    Py_VISIT(mod_state->ZstdDict_type);
    Py_VISIT(mod_state->ZstdCompressor_type);

    Py_VISIT(mod_state->ZstdDecompressor_type);

    Py_VISIT(mod_state->ZstdError);

    Py_VISIT(mod_state->CParameter_type);
    Py_VISIT(mod_state->DParameter_type);
    return 0;
}

static int
_zstd_clear(PyObject *module)
{
    _zstd_state* const mod_state = get_zstd_state(module);

    Py_CLEAR(mod_state->ZstdDict_type);
    Py_CLEAR(mod_state->ZstdCompressor_type);

    Py_CLEAR(mod_state->ZstdDecompressor_type);

    Py_CLEAR(mod_state->ZstdError);

    Py_CLEAR(mod_state->CParameter_type);
    Py_CLEAR(mod_state->DParameter_type);
    return 0;
}

static void
_zstd_free(void *module)
{
    (void)_zstd_clear((PyObject *)module);
}

static struct PyModuleDef_Slot _zstd_slots[] = {
    {Py_mod_exec, _zstd_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL},
};

static struct PyModuleDef _zstdmodule = {
    .m_base = PyModuleDef_HEAD_INIT,
    .m_name = "_zstd",
    .m_doc = "Implementation module for Zstandard compression.",
    .m_size = sizeof(_zstd_state),
    .m_slots = _zstd_slots,
    .m_methods = _zstd_methods,
    .m_traverse = _zstd_traverse,
    .m_clear = _zstd_clear,
    .m_free = _zstd_free,
};

PyMODINIT_FUNC
PyInit__zstd(void)
{
    return PyModuleDef_Init(&_zstdmodule);
}
