/* t-string Interpolation object implementation */

#include "Python.h"
#include "pycore_initconfig.h"    // _PyStatus_OK
#include "pycore_interpolation.h"
#include "pycore_typeobject.h"    // _PyType_GetDict

static int
_conversion_converter(PyObject *arg, PyObject **conversion)
{
    if (arg == Py_None) {
        return 1;
    }

    if (!PyUnicode_Check(arg)) {
        PyErr_Format(PyExc_TypeError,
            "Interpolation() argument 'conversion' must be str, not %T",
            arg);
        return 0;
    }

    Py_ssize_t len;
    const char *conv_str = PyUnicode_AsUTF8AndSize(arg, &len);
    if (len != 1 || !(conv_str[0] == 'a' || conv_str[0] == 'r' || conv_str[0] == 's')) {
        PyErr_SetString(PyExc_ValueError,
            "Interpolation() argument 'conversion' must be one of 's', 'a' or 'r'");
        return 0;
    }

    *conversion = arg;
    return 1;
}

#include "clinic/interpolationobject.c.h"

/*[clinic input]
class Interpolation "interpolationobject *" "&_PyInterpolation_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=161c64a16f9c4544]*/

typedef struct {
    PyObject_HEAD
    PyObject *value;
    PyObject *expression;
    PyObject *conversion;
    PyObject *format_spec;
} interpolationobject;

#define interpolationobject_CAST(op) \
    (assert(_PyInterpolation_CheckExact(op)), _Py_CAST(interpolationobject*, (op)))

/*[clinic input]
@classmethod
Interpolation.__new__ as interpolation_new

    value: object
    expression: object(subclass_of='&PyUnicode_Type', c_default='&_Py_STR(empty)') = ""
    conversion: object(converter='_conversion_converter') = None
    format_spec: object(subclass_of='&PyUnicode_Type', c_default='&_Py_STR(empty)') = ""
[clinic start generated code]*/

static PyObject *
interpolation_new_impl(PyTypeObject *type, PyObject *value,
                       PyObject *expression, PyObject *conversion,
                       PyObject *format_spec)
/*[clinic end generated code: output=6488e288765bc1a9 input=fc5c285c1dd23d36]*/
{
    interpolationobject *self = PyObject_GC_New(interpolationobject, type);
    if (!self) {
        return NULL;
    }

    self->value = Py_NewRef(value);
    self->expression = Py_NewRef(expression);
    self->conversion = Py_NewRef(conversion);
    self->format_spec = Py_NewRef(format_spec);
    PyObject_GC_Track(self);
    return (PyObject *) self;
}

static void
interpolation_dealloc(PyObject *op)
{
    PyObject_GC_UnTrack(op);
    Py_TYPE(op)->tp_clear(op);
    Py_TYPE(op)->tp_free(op);
}

static int
interpolation_clear(PyObject *op)
{
    interpolationobject *self = interpolationobject_CAST(op);
    Py_CLEAR(self->value);
    Py_CLEAR(self->expression);
    Py_CLEAR(self->conversion);
    Py_CLEAR(self->format_spec);
    return 0;
}

static int
interpolation_traverse(PyObject *op, visitproc visit, void *arg)
{
    interpolationobject *self = interpolationobject_CAST(op);
    Py_VISIT(self->value);
    Py_VISIT(self->expression);
    Py_VISIT(self->conversion);
    Py_VISIT(self->format_spec);
    return 0;
}

static PyObject *
interpolation_repr(PyObject *op)
{
    interpolationobject *self = interpolationobject_CAST(op);
    return PyUnicode_FromFormat("%s(%R, %R, %R, %R)",
                                _PyType_Name(Py_TYPE(self)), self->value, self->expression,
                                self->conversion, self->format_spec);
}

static PyMemberDef interpolation_members[] = {
    {"value", Py_T_OBJECT_EX, offsetof(interpolationobject, value), Py_READONLY, "Value"},
    {"expression", Py_T_OBJECT_EX, offsetof(interpolationobject, expression), Py_READONLY, "Expression"},
    {"conversion", Py_T_OBJECT_EX, offsetof(interpolationobject, conversion), Py_READONLY, "Conversion"},
    {"format_spec", Py_T_OBJECT_EX, offsetof(interpolationobject, format_spec), Py_READONLY, "Format specifier"},
    {NULL}
};

static PyObject*
interpolation_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
{
    interpolationobject *self = interpolationobject_CAST(op);
    return Py_BuildValue("(O(OOOO))", (PyObject *)Py_TYPE(op),
                         self->value, self->expression,
                         self->conversion, self->format_spec);
}

static PyMethodDef interpolation_methods[] = {
    {"__reduce__", interpolation_reduce, METH_NOARGS,
        PyDoc_STR("__reduce__() -> (cls, state)")},
    {"__class_getitem__", Py_GenericAlias,
        METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
    {NULL, NULL},
};

PyTypeObject _PyInterpolation_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    .tp_name = "string.templatelib.Interpolation",
    .tp_doc = PyDoc_STR("Interpolation object"),
    .tp_basicsize = sizeof(interpolationobject),
    .tp_itemsize = 0,
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
    .tp_new = interpolation_new,
    .tp_alloc = PyType_GenericAlloc,
    .tp_dealloc = interpolation_dealloc,
    .tp_clear = interpolation_clear,
    .tp_free = PyObject_GC_Del,
    .tp_repr = interpolation_repr,
    .tp_members = interpolation_members,
    .tp_methods = interpolation_methods,
    .tp_traverse = interpolation_traverse,
};

PyStatus
_PyInterpolation_InitTypes(PyInterpreterState *interp)
{
    PyObject *tuple = Py_BuildValue("(ssss)", "value", "expression", "conversion", "format_spec");
    if (!tuple) {
        goto error;
    }

    PyObject *dict = _PyType_GetDict(&_PyInterpolation_Type);
    if (!dict) {
        Py_DECREF(tuple);
        goto error;
    }

    int status = PyDict_SetItemString(dict, "__match_args__", tuple);
    Py_DECREF(tuple);
    if (status < 0) {
        goto error;
    }
    return _PyStatus_OK();

error:
    return _PyStatus_ERR("Can't initialize interpolation types");
}

PyObject *
_PyInterpolation_Build(PyObject *value, PyObject *str, int conversion, PyObject *format_spec)
{
    interpolationobject *interpolation = PyObject_GC_New(interpolationobject, &_PyInterpolation_Type);
    if (!interpolation) {
        return NULL;
    }

    interpolation->value = Py_NewRef(value);
    interpolation->expression = Py_NewRef(str);
    interpolation->format_spec = Py_NewRef(format_spec);
    interpolation->conversion = NULL;

    if (conversion == 0) {
        interpolation->conversion = Py_None;
    }
    else {
        switch (conversion) {
            case FVC_ASCII:
                interpolation->conversion = _Py_LATIN1_CHR('a');
                break;
            case FVC_REPR:
                interpolation->conversion = _Py_LATIN1_CHR('r');
                break;
            case FVC_STR:
                interpolation->conversion = _Py_LATIN1_CHR('s');
                break;
            default:
                PyErr_SetString(PyExc_SystemError,
                    "Interpolation() argument 'conversion' must be one of 's', 'a' or 'r'");
                Py_DECREF(interpolation);
                return NULL;
        }
    }

    PyObject_GC_Track(interpolation);
    return (PyObject *) interpolation;
}

PyObject *
_PyInterpolation_GetValueRef(PyObject *interpolation)
{
    return Py_NewRef(interpolationobject_CAST(interpolation)->value);
}
