#include "Python.h"
#include "errcode.h"
#include "internal/pycore_critical_section.h"   // Py_BEGIN_CRITICAL_SECTION
#include "../Parser/tokenizer/tokenizer.h"
#include "../Parser/pegen.h"                    // _PyPegen_byte_offset_to_character_offset()

static struct PyModuleDef _tokenizemodule;

typedef struct {
    PyTypeObject *TokenizerIter;
} tokenize_state;

static tokenize_state *
get_tokenize_state(PyObject *module) {
    return (tokenize_state *)PyModule_GetState(module);
}

#define _tokenize_get_state_by_type(type) \
    get_tokenize_state(PyType_GetModuleByDef(type, &_tokenizemodule))

#include "pycore_runtime.h"
#include "clinic/Python-tokenize.c.h"

/*[clinic input]
module _tokenizer
class _tokenizer.tokenizeriter "tokenizeriterobject *" "_tokenize_get_state_by_type(type)->TokenizerIter"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=96d98ee2fef7a8bc]*/

typedef struct
{
    PyObject_HEAD struct tok_state *tok;
    int done;
    int extra_tokens;

    /* Needed to cache line for performance */
    PyObject *last_line;
    Py_ssize_t last_lineno;
    Py_ssize_t byte_col_offset_diff;
} tokenizeriterobject;

/*[clinic input]
@classmethod
_tokenizer.tokenizeriter.__new__ as tokenizeriter_new

    readline: object
    /
    *
    extra_tokens: bool
    encoding: str(c_default="NULL") = 'utf-8'
[clinic start generated code]*/

static PyObject *
tokenizeriter_new_impl(PyTypeObject *type, PyObject *readline,
                       int extra_tokens, const char *encoding)
/*[clinic end generated code: output=7501a1211683ce16 input=f7dddf8a613ae8bd]*/
{
    struct tok_state *tok = _PyTokenizer_FromReadline(readline, encoding);
    if (tok == NULL) {
        return NULL;
    }
    _Py_DECLARE_STR(anon_string, "<string>");
    _PyTokenizer_SetContext(tok, &_Py_STR(anon_string), NULL);
    tokenizeriterobject *self = (tokenizeriterobject *)type->tp_alloc(type, 0);
    if (self == NULL) {
        _PyTokenizer_Free(tok);
        return NULL;
    }
    self->tok = tok;
    _PyTokenizer_SetOptions(self->tok, extra_tokens, 0);
    self->extra_tokens = extra_tokens;
    self->done = 0;

    self->last_line = NULL;
    self->byte_col_offset_diff = 0;
    self->last_lineno = 0;

    return (PyObject *)self;
}

static void
_tokenizer_error(tokenizeriterobject *it)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(it);
    assert(!PyErr_Occurred());

    const char *msg = NULL;
    PyObject* errtype = PyExc_SyntaxError;
    struct tok_state *tok = it->tok;
    _PyTokenizer_Info info = _PyTokenizer_GetInfo(tok);
    switch (info.status) {
        case E_TOKEN:
            msg = "invalid token";
            break;
        case E_EOF:
            PyErr_SetString(PyExc_SyntaxError, "unexpected EOF in multi-line statement");
            PyErr_SyntaxLocationObject(
                info.filename, info.location.lineno,
                (int)Py_MAX(0, info.input_span.end - info.input_span.start));
            return;
        case E_DEDENT:
            msg = "unindent does not match any outer indentation level";
            errtype = PyExc_IndentationError;
            break;
        case E_INTR:
            PyErr_SetNone(PyExc_KeyboardInterrupt);
            return;
        case E_NOMEM:
            PyErr_NoMemory();
            return;
        case E_TABSPACE:
            errtype = PyExc_TabError;
            msg = "inconsistent use of tabs and spaces in indentation";
            break;
        case E_TOODEEP:
            errtype = PyExc_IndentationError;
            msg = "too many levels of indentation";
            break;
        case E_LINECONT: {
            msg = "unexpected character after line continuation character";
            break;
        }
        default:
            msg = "unknown tokenization error";
    }

    PyObject* error_line = NULL;
    PyObject* value = NULL;

    Py_ssize_t input_size;
    const char *input = _PyTokenizer_SpanView(
        tok, info.input_span, &input_size);
    Py_ssize_t size = input_size;
    assert(input[size-1] == '\n');
    size -= 1; // Remove the newline character from the end of the line
    error_line = PyUnicode_DecodeUTF8(input, size, "replace");
    if (!error_line) {
        goto exit;
    }

    Py_ssize_t offset = _PyPegen_byte_offset_to_character_offset(error_line, input_size);
    if (offset == -1) {
        goto exit;
    }
    value = Py_BuildValue("(s(OinOOO))", msg, info.filename,
                          info.location.lineno, offset, error_line,
                          Py_None, Py_None);
    if (!value) {
        goto exit;
    }

    PyErr_SetObject(errtype, value);

exit:
    Py_XDECREF(error_line);
    Py_XDECREF(value);
}

static PyObject *
_get_current_line(tokenizeriterobject *it, int current_lineno,
                  const _PyToken_View *view, int *line_changed)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(it);
    if (current_lineno != it->last_lineno) {
        Py_ssize_t size;
        const char *line_start = _PyTokenizer_SpanView(
            it->tok, view->line_span, &size);
        if (size > 0 && view->implicit_newline) {
            size--;
        }
        Py_XDECREF(it->last_line);
        it->last_line = PyUnicode_DecodeUTF8(line_start, size, "replace");
        it->byte_col_offset_diff = 0;
    }
    else {
        *line_changed = 0;
    }
    return it->last_line;
}

static int
_get_col_offsets(tokenizeriterobject *it, const struct token *token,
                 const _PyToken_View *view, PyObject *line, int line_changed,
                 Py_ssize_t *col_offset, Py_ssize_t *end_col_offset)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(it);
    _PyTok_Off token_start = token->span.start;
    _PyTok_Off token_end = token->span.end;
    Py_ssize_t lineno = token->start_loc.lineno;
    Py_ssize_t end_lineno = token->end_loc.lineno;
    Py_ssize_t byte_offset = -1;
    if (token_start >= view->line_span.start) {
        byte_offset = token_start - view->line_span.start;
        if (line_changed) {
            *col_offset = _PyPegen_byte_offset_to_character_offset_line(line, 0, byte_offset);
            if (*col_offset < 0) {
                return -1;
            }
            it->byte_col_offset_diff = byte_offset - *col_offset;
        }
        else {
            *col_offset = byte_offset - it->byte_col_offset_diff;
        }
    }

    if (token_end >= view->end_line_start) {
        Py_ssize_t end_byte_offset = token_end - view->end_line_start;
        if (lineno == end_lineno) {
            // Avoid rescanning the prefix of a very long line.
            Py_ssize_t token_col_offset = _PyPegen_byte_offset_to_character_offset_line(line, byte_offset, end_byte_offset);
            if (token_col_offset < 0) {
                return -1;
            }
            *end_col_offset = *col_offset + token_col_offset;
            it->byte_col_offset_diff += token_end - token_start - token_col_offset;
        }
        else {
            *end_col_offset = _PyPegen_byte_offset_to_character_offset_line(
                line, view->end_line_start - view->line_span.start,
                token_end - view->line_span.start);
            if (*end_col_offset < 0) {
                return -1;
            }
            it->byte_col_offset_diff += end_byte_offset - *end_col_offset;
        }
    }
    it->last_lineno = lineno;
    return 0;
}

static PyObject *
tokenizeriter_next(PyObject *op)
{
    tokenizeriterobject *it = (tokenizeriterobject*)op;
    PyObject* result = NULL;

    Py_BEGIN_CRITICAL_SECTION(it);

    if (it->done) {
        PyErr_SetString(PyExc_StopIteration, "EOF");
        goto unlock;
    }

    struct token token;
    _PyToken_Init(&token);

    _PyTokenizer_Get(it->tok, &token);
    int type = token.type;
    if (type == ERRORTOKEN) {
        if(!PyErr_Occurred()) {
            _tokenizer_error(it);
            assert(PyErr_Occurred());
        }
        goto exit;
    }
    _PyToken_View view;
    _PyToken_GetView(it->tok, &token, &view);
    PyObject *str = PyUnicode_FromStringAndSize(view.text, view.length);
    if (str == NULL) {
        goto exit;
    }

    int is_trailing_token = type == ENDMARKER || (type == DEDENT && view.at_eof);

    PyObject* line = NULL;
    int line_changed = 1;
    if (it->extra_tokens && is_trailing_token) {
        line = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
    } else {
        line = _get_current_line(
            it, token.end_loc.lineno, &view, &line_changed);
    }
    if (line == NULL) {
        Py_DECREF(str);
        goto exit;
    }

    Py_ssize_t lineno = token.start_loc.lineno;
    Py_ssize_t end_lineno = token.end_loc.lineno;
    Py_ssize_t col_offset = -1;
    Py_ssize_t end_col_offset = -1;
    if (_get_col_offsets(it, &token, &view, line,
                         line_changed, &col_offset, &end_col_offset) < 0) {
        Py_DECREF(str);
        goto exit;
    }

    if (it->extra_tokens) {
        if (is_trailing_token) {
            lineno = end_lineno = lineno + 1;
            col_offset = end_col_offset = 0;
        }
        // Necessary adjustments to match the original Python tokenize
        // implementation
        if (type > DEDENT && type < OP) {
            type = OP;
        }
        else if (type == NEWLINE) {
            if (!view.implicit_newline) {
                Py_DECREF(str);
                if (view.text[0] == '\r') {
                    str = PyUnicode_FromString("\r\n");
                } else {
                    str = PyUnicode_FromString("\n");
                }
            }
            end_col_offset++;
        }
        else if (type == NL) {
            if (view.implicit_newline) {
                Py_DECREF(str);
                str = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
            }
        }

        if (str == NULL) {
            goto exit;
        }
    }

    result = Py_BuildValue("(iN(nn)(nn)O)", type, str, lineno, col_offset, end_lineno, end_col_offset, line);
exit:
    _PyToken_Free(&token);
    if (type == ENDMARKER) {
        it->done = 1;
    }

unlock:;
    Py_END_CRITICAL_SECTION();
    return result;
}

static void
tokenizeriter_dealloc(PyObject *op)
{
    tokenizeriterobject *it = (tokenizeriterobject*)op;
    PyTypeObject *tp = Py_TYPE(it);
    PyObject_GC_UnTrack(it);
    Py_XDECREF(it->last_line);
    _PyTokenizer_Free(it->tok);
    tp->tp_free(it);
    Py_DECREF(tp);
}

static int
tokenizeriter_traverse(PyObject *op, visitproc visit, void *arg)
{
    tokenizeriterobject *it = (tokenizeriterobject *)op;
    Py_VISIT(Py_TYPE(it));
    Py_VISIT(it->last_line);
    return _PyTokenizer_Traverse(it->tok, visit, arg);
}

static PyType_Slot tokenizeriter_slots[] = {
    {Py_tp_new, tokenizeriter_new},
    {Py_tp_dealloc, tokenizeriter_dealloc},
    {Py_tp_traverse, tokenizeriter_traverse},
    {Py_tp_getattro, PyObject_GenericGetAttr},
    {Py_tp_iter, PyObject_SelfIter},
    {Py_tp_iternext, tokenizeriter_next},
    {0, NULL},
};

static PyType_Spec tokenizeriter_spec = {
    .name = "_tokenize.TokenizerIter",
    .basicsize = sizeof(tokenizeriterobject),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
    .slots = tokenizeriter_slots,
};

static int
tokenizemodule_exec(PyObject *m)
{
    tokenize_state *state = get_tokenize_state(m);
    if (state == NULL) {
        return -1;
    }

    state->TokenizerIter = (PyTypeObject *)PyType_FromModuleAndSpec(m, &tokenizeriter_spec, NULL);
    if (state->TokenizerIter == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, state->TokenizerIter) < 0) {
        return -1;
    }

    return 0;
}

static PyMethodDef tokenize_methods[] = {
    {NULL, NULL, 0, NULL} /* Sentinel */
};

static PyModuleDef_Slot tokenizemodule_slots[] = {
    _Py_ABI_SLOT,
    {Py_mod_exec, tokenizemodule_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static int
tokenizemodule_traverse(PyObject *m, visitproc visit, void *arg)
{
    tokenize_state *state = get_tokenize_state(m);
    Py_VISIT(state->TokenizerIter);
    return 0;
}

static int
tokenizemodule_clear(PyObject *m)
{
    tokenize_state *state = get_tokenize_state(m);
    Py_CLEAR(state->TokenizerIter);
    return 0;
}

static void
tokenizemodule_free(void *m)
{
    tokenizemodule_clear((PyObject *)m);
}

static struct PyModuleDef _tokenizemodule = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_tokenize",
    .m_size = sizeof(tokenize_state),
    .m_slots = tokenizemodule_slots,
    .m_methods = tokenize_methods,
    .m_traverse = tokenizemodule_traverse,
    .m_clear = tokenizemodule_clear,
    .m_free = tokenizemodule_free,
};

PyMODINIT_FUNC
PyInit__tokenize(void)
{
    return PyModuleDef_Init(&_tokenizemodule);
}
