/* 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* 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* 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* 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* 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* 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* 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* 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* 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* 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* 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);
}
