#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "parts.h"
#include "util.h"
#include "clinic/long.c.h"

/*[clinic input]
module _testcapi
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/


/*[clinic input]
_testcapi.call_long_compact_api
    arg: object
    /
[clinic start generated code]*/

static PyObject *
_testcapi_call_long_compact_api(PyObject *module, PyObject *arg)
/*[clinic end generated code: output=7e3894f611b1b2b7 input=87b87396967af14c]*/

{
    assert(PyLong_Check(arg));
    int is_compact = PyUnstable_Long_IsCompact((PyLongObject*)arg);
    Py_ssize_t value = -1;
    if (is_compact) {
        value = PyUnstable_Long_CompactValue((PyLongObject*)arg);
    }
    return Py_BuildValue("in", is_compact, value);
}


static PyObject *
pylong_fromunicodeobject(PyObject *module, PyObject *args)
{
    PyObject *unicode;
    int base;
    if (!PyArg_ParseTuple(args, "Oi", &unicode, &base)) {
        return NULL;
    }

    NULLABLE(unicode);
    return PyLong_FromUnicodeObject(unicode, base);
}


static PyObject *
pylong_asnativebytes(PyObject *module, PyObject *args)
{
    PyObject *v;
    Py_buffer buffer;
    Py_ssize_t n, flags;
    if (!PyArg_ParseTuple(args, "Ow*nn", &v, &buffer, &n, &flags)) {
        return NULL;
    }
    if (buffer.readonly) {
        PyErr_SetString(PyExc_TypeError, "buffer must be writable");
        PyBuffer_Release(&buffer);
        return NULL;
    }
    if (buffer.len < n) {
        PyErr_SetString(PyExc_ValueError, "buffer must be at least 'n' bytes");
        PyBuffer_Release(&buffer);
        return NULL;
    }
    Py_ssize_t res = PyLong_AsNativeBytes(v, buffer.buf, n, (int)flags);
    PyBuffer_Release(&buffer);
    return res >= 0 ? PyLong_FromSsize_t(res) : NULL;
}


static PyObject *
pylong_fromnativebytes(PyObject *module, PyObject *args)
{
    Py_buffer buffer;
    Py_ssize_t n, flags, signed_;
    if (!PyArg_ParseTuple(args, "y*nnn", &buffer, &n, &flags, &signed_)) {
        return NULL;
    }
    if (buffer.len < n) {
        PyErr_SetString(PyExc_ValueError, "buffer must be at least 'n' bytes");
        PyBuffer_Release(&buffer);
        return NULL;
    }
    PyObject *res = signed_
        ? PyLong_FromNativeBytes(buffer.buf, n, (int)flags)
        : PyLong_FromUnsignedNativeBytes(buffer.buf, n, (int)flags);
    PyBuffer_Release(&buffer);
    return res;
}


static PyObject *
pylong_getsign(PyObject *module, PyObject *arg)
{
    int sign;
    NULLABLE(arg);
    if (PyLong_GetSign(arg, &sign) == -1) {
        return NULL;
    }
    return PyLong_FromLong(sign);
}


static PyObject *
pylong_ispositive(PyObject *module, PyObject *arg)
{
    NULLABLE(arg);
    RETURN_INT(PyLong_IsPositive(arg));
}


static PyObject *
pylong_isnegative(PyObject *module, PyObject *arg)
{
    NULLABLE(arg);
    RETURN_INT(PyLong_IsNegative(arg));
}


static PyObject *
pylong_iszero(PyObject *module, PyObject *arg)
{
    NULLABLE(arg);
    RETURN_INT(PyLong_IsZero(arg));
}


static PyObject *
pylong_aspid(PyObject *module, PyObject *arg)
{
    NULLABLE(arg);
    pid_t value = PyLong_AsPid(arg);
    if (value == -1 && PyErr_Occurred()) {
        return NULL;
    }
    return PyLong_FromPid(value);
}


static PyObject *
layout_to_dict(const PyLongLayout *layout)
{
    return Py_BuildValue("{sisisisi}",
        "bits_per_digit", (int)layout->bits_per_digit,
        "digit_size", (int)layout->digit_size,
        "digits_order", (int)layout->digits_order,
        "digit_endianness", (int)layout->digit_endianness);
}


static PyObject *
pylong_export(PyObject *module, PyObject *obj)
{
    PyLongExport export_long;
    if (PyLong_Export(obj, &export_long) < 0) {
        return NULL;
    }

    if (export_long.digits == NULL) {
        assert(export_long.negative == 0);
        assert(export_long.ndigits == 0);
        assert(export_long.digits == NULL);
        PyObject *res = PyLong_FromInt64(export_long.value);
        PyLong_FreeExport(&export_long);
        return res;
    }

    assert(PyLong_GetNativeLayout()->digit_size == sizeof(digit));
    const digit *export_long_digits = export_long.digits;

    PyObject *digits = PyList_New(0);
    if (digits == NULL) {
        goto error;
    }
    for (Py_ssize_t i = 0; i < export_long.ndigits; i++) {
        PyObject *item = PyLong_FromUnsignedLong(export_long_digits[i]);
        if (item == NULL) {
            goto error;
        }

        if (PyList_Append(digits, item) < 0) {
            Py_DECREF(item);
            goto error;
        }
        Py_DECREF(item);
    }

    assert(export_long.value == 0);
    PyObject *res = Py_BuildValue("(iN)", export_long.negative, digits);

    PyLong_FreeExport(&export_long);
    assert(export_long._reserved == 0);

    return res;

error:
    Py_XDECREF(digits);
    PyLong_FreeExport(&export_long);
    return NULL;
}


static PyObject *
pylongwriter_create(PyObject *module, PyObject *args)
{
    int negative;
    PyObject *list;
    // TODO(vstinner): write test for negative ndigits and digits==NULL
    if (!PyArg_ParseTuple(args, "iO!", &negative, &PyList_Type, &list)) {
        return NULL;
    }
    Py_ssize_t ndigits = PyList_GET_SIZE(list);

    digit *digits = PyMem_Malloc((size_t)ndigits * sizeof(digit));
    if (digits == NULL) {
        return PyErr_NoMemory();
    }

    for (Py_ssize_t i = 0; i < ndigits; i++) {
        PyObject *item = PyList_GET_ITEM(list, i);

        long num = PyLong_AsLong(item);
        if (num == -1 && PyErr_Occurred()) {
            goto error;
        }

        if (num < 0 || num >= (long)PyLong_BASE) {
            PyErr_SetString(PyExc_ValueError, "digit doesn't fit into digit");
            goto error;
        }
        digits[i] = (digit)num;
    }

    void *writer_digits;
    PyLongWriter *writer = PyLongWriter_Create(negative, ndigits,
                                               &writer_digits);
    if (writer == NULL) {
        goto error;
    }
    assert(PyLong_GetNativeLayout()->digit_size == sizeof(digit));
    memcpy(writer_digits, digits, (size_t)ndigits * sizeof(digit));
    PyObject *res = PyLongWriter_Finish(writer);
    PyMem_Free(digits);

    return res;

error:
    PyMem_Free(digits);
    return NULL;
}


static PyObject *
get_pylong_layout(PyObject *module, PyObject *Py_UNUSED(args))
{
    const PyLongLayout *layout = PyLong_GetNativeLayout();
    return layout_to_dict(layout);
}


static PyMethodDef test_methods[] = {
    _TESTCAPI_CALL_LONG_COMPACT_API_METHODDEF
    {"pylong_fromunicodeobject",    pylong_fromunicodeobject,   METH_VARARGS},
    {"pylong_asnativebytes",        pylong_asnativebytes,       METH_VARARGS},
    {"pylong_fromnativebytes",      pylong_fromnativebytes,     METH_VARARGS},
    {"pylong_getsign",              pylong_getsign,             METH_O},
    {"pylong_aspid",                pylong_aspid,               METH_O},
    {"pylong_export",               pylong_export,              METH_O},
    {"pylongwriter_create",         pylongwriter_create,        METH_VARARGS},
    {"get_pylong_layout",           get_pylong_layout,          METH_NOARGS},
    {"pylong_ispositive",           pylong_ispositive,          METH_O},
    {"pylong_isnegative",           pylong_isnegative,          METH_O},
    {"pylong_iszero",               pylong_iszero,              METH_O},
    {NULL},
};

int
_PyTestCapi_Init_Long(PyObject *mod)
{
    if (PyModule_AddFunctions(mod, test_methods) < 0) {
        return -1;
    }
    return 0;
}
