/* PyInterpreterConfig API */

#include "Python.h"
#include "pycore_interp.h" // Py_RTFLAGS
#include "pycore_pylifecycle.h"

#include <stdbool.h>

#include "config_common.h"


static const char *
gil_flag_to_str(int flag)
{
    switch (flag) {
    case PyInterpreterConfig_DEFAULT_GIL:
        return "default";
    case PyInterpreterConfig_SHARED_GIL:
        return "shared";
    case PyInterpreterConfig_OWN_GIL:
        return "own";
    default:
        PyErr_SetString(PyExc_SystemError,
                        "invalid interpreter config 'gil' value");
        return NULL;
    }
}

static int
gil_flag_from_str(const char *str, int *p_flag)
{
    int flag;
    if (str == NULL) {
        flag = PyInterpreterConfig_DEFAULT_GIL;
    }
    else if (strcmp(str, "default") == 0) {
        flag = PyInterpreterConfig_DEFAULT_GIL;
    }
    else if (strcmp(str, "shared") == 0) {
        flag = PyInterpreterConfig_SHARED_GIL;
    }
    else if (strcmp(str, "own") == 0) {
        flag = PyInterpreterConfig_OWN_GIL;
    }
    else {
        PyErr_Format(PyExc_ValueError,
                     "unsupported interpreter config .gil value '%s'", str);
        return -1;
    }
    *p_flag = flag;
    return 0;
}

PyObject *
_PyInterpreterConfig_AsDict(PyInterpreterConfig *config)
{
    PyObject *dict = PyDict_New();
    if (dict == NULL) {
        return NULL;
    }

#define ADD(NAME, OBJ)                                              \
        do {                                                        \
            int res = PyDict_SetItemString(dict, NAME, (OBJ));      \
            Py_DECREF(OBJ);                                         \
            if (res < 0) {                                          \
                goto error;                                         \
            }                                                       \
        } while (0)
#define ADD_BOOL(FIELD) \
        ADD(#FIELD, Py_NewRef(config->FIELD ? Py_True : Py_False))
#define ADD_STR(FIELD, STR)                                         \
        do {                                                        \
            if (STR == NULL) {                                      \
                goto error;                                         \
            }                                                       \
            PyObject *obj = PyUnicode_FromString(STR);              \
            if (obj == NULL) {                                      \
                goto error;                                         \
            }                                                       \
            ADD(#FIELD, obj);                                       \
        } while (0)

    ADD_BOOL(use_main_obmalloc);
    ADD_BOOL(allow_fork);
    ADD_BOOL(allow_exec);
    ADD_BOOL(allow_threads);
    ADD_BOOL(allow_daemon_threads);
    ADD_BOOL(check_multi_interp_extensions);

    ADD_STR(gil, gil_flag_to_str(config->gil));

#undef ADD_STR
#undef ADD_BOOL
#undef ADD

    return dict;

error:
    Py_DECREF(dict);
    return NULL;
}

static int
_config_dict_get_bool(PyObject *dict, const char *name, int *p_flag)
{
    PyObject *item;
    if (_config_dict_get(dict, name, &item) < 0) {
        return -1;
    }
    // For now we keep things strict, rather than using PyObject_IsTrue().
    int flag = item == Py_True;
    if (!flag && item != Py_False) {
        Py_DECREF(item);
        config_dict_invalid_type(name);
        return -1;
    }
    Py_DECREF(item);
    *p_flag = flag;
    return 0;
}

static int
_config_dict_copy_str(PyObject *dict, const char *name,
                      char *buf, size_t bufsize)
{
    PyObject *item;
    if (_config_dict_get(dict, name, &item) < 0) {
        return -1;
    }
    if (!PyUnicode_Check(item)) {
        Py_DECREF(item);
        config_dict_invalid_type(name);
        return -1;
    }
    const char *str = PyUnicode_AsUTF8(item);
    if (str == NULL) {
        Py_DECREF(item);
        return -1;
    }
    strncpy(buf, str, bufsize-1);
    buf[bufsize-1] = '\0';
    Py_DECREF(item);
    return 0;
}

static int
interp_config_from_dict(PyObject *origdict, PyInterpreterConfig *config,
                        bool missing_allowed)
{
    PyObject *dict = PyDict_New();
    if (dict == NULL) {
        return -1;
    }
    if (PyDict_Update(dict, origdict) < 0) {
        goto error;
    }

#define CHECK(NAME)                                                 \
    do {                                                            \
        if (PyErr_Occurred()) {                                     \
            goto error;                                             \
        }                                                           \
        else {                                                      \
            if (!missing_allowed) {                                 \
                (void)config_dict_get(dict, NAME);                  \
                assert(PyErr_Occurred());                           \
                goto error;                                         \
            }                                                       \
        }                                                           \
    } while (0)
#define COPY_BOOL(FIELD)                                            \
    do {                                                            \
        int flag;                                                   \
        if (_config_dict_get_bool(dict, #FIELD, &flag) < 0) {       \
            CHECK(#FIELD);                                          \
        }                                                           \
        else {                                                      \
            config->FIELD = flag;                                   \
            (void)PyDict_PopString(dict, #FIELD, NULL);             \
        }                                                           \
    } while (0)

    COPY_BOOL(use_main_obmalloc);
    COPY_BOOL(allow_fork);
    COPY_BOOL(allow_exec);
    COPY_BOOL(allow_threads);
    COPY_BOOL(allow_daemon_threads);
    COPY_BOOL(check_multi_interp_extensions);

    // PyInterpreterConfig.gil
    char buf[20];
    if (_config_dict_copy_str(dict, "gil", buf, 20) < 0) {
        CHECK("gil");
    }
    else {
        int flag;
        if (gil_flag_from_str(buf, &flag) < 0) {
            goto error;
        }
        config->gil = flag;
        (void)PyDict_PopString(dict, "gil", NULL);
    }

#undef COPY_BOOL
#undef CHECK

    Py_ssize_t unused = PyDict_GET_SIZE(dict);
    if (unused == 1) {
        PyErr_Format(PyExc_ValueError,
                     "config dict has 1 extra item (%R)", dict);
        goto error;
    }
    else if (unused > 0) {
        PyErr_Format(PyExc_ValueError,
                     "config dict has %zd extra items (%R)", unused, dict);
        goto error;
    }

    Py_DECREF(dict);
    return 0;

error:
    Py_DECREF(dict);
    return -1;
}

int
_PyInterpreterConfig_InitFromDict(PyInterpreterConfig *config, PyObject *dict)
{
    if (!PyDict_Check(dict)) {
        PyErr_SetString(PyExc_TypeError, "dict expected");
        return -1;
    }
    if (interp_config_from_dict(dict, config, false) < 0) {
        return -1;
    }
    return 0;
}

int
_PyInterpreterConfig_UpdateFromDict(PyInterpreterConfig *config, PyObject *dict)
{
    if (!PyDict_Check(dict)) {
        PyErr_SetString(PyExc_TypeError, "dict expected");
        return -1;
    }
    if (interp_config_from_dict(dict, config, true) < 0) {
        return -1;
    }
    return 0;
}

int
_PyInterpreterConfig_InitFromState(PyInterpreterConfig *config,
                                   PyInterpreterState *interp)
{
    // Populate the config by re-constructing the values from the interpreter.
    *config = (PyInterpreterConfig){
#define FLAG(flag) \
        (interp->feature_flags & Py_RTFLAGS_ ## flag)
        .use_main_obmalloc = FLAG(USE_MAIN_OBMALLOC),
        .allow_fork = FLAG(FORK),
        .allow_exec = FLAG(EXEC),
        .allow_threads = FLAG(THREADS),
        .allow_daemon_threads = FLAG(DAEMON_THREADS),
        .check_multi_interp_extensions = FLAG(MULTI_INTERP_EXTENSIONS),
#undef FLAG
        .gil = interp->ceval.own_gil
            ? PyInterpreterConfig_OWN_GIL
            : PyInterpreterConfig_SHARED_GIL,
    };
    return 0;
}
