import pytest

import yuio.rst

TEST_CASES = [
    "Simple paragraph",
    "Two paragraphs\n\nSecond paragraph",
    "Title\n=====",
    "Section\n-------",
    "Subsection\n~~~~~~~~~~",
    "=====\nTitle\n=====",
    "-------\nSection\n-------",
    "Title 1\n=======\n\nTitle 2\n=======",
    "Title\n=====\n\nSection\n-------",
    "* Item 1\n* Item 2\n* Item 3",
    "- Item 1\n- Item 2",
    "+ Item 1\n+ Item 2",
    "• Item 1\n• Item 2",
    "* Item 1\n  continued\n* Item 2",
    "*\n  Item 1",
    "* Item 1\n  continued",
    "-  List 2\n   Continuation\n  Not a continuation",
    "- List\n-\n- List",
    "1. First\n2. Second\n3. Third",
    "1) First\n2) Second",
    "(1) First\n(2) Second",
    "A) This is not\na list",
    "1) This is not a list...\n2. because list style changes without a blank line.",
    "1) This is a list...\n2) because list style doesn't change.",
    "\\A. Einstein was a really smart dude.",
    "1. Item 1 initial text.\n\n   a) Item 1a.\n   b) Item 1b.\n\n2. a) Item 2a.\n   b) Item 2b.",
    "1. List\n2.\n3. List",
    "#. First\n#. Second\n#. Third",
    "a. First\n#. Second\n#. Third",
    "A. First\nB. Second",
    "i. First\nii. Second\niii. Third",
    "I. First\nII. Second\nIII. Third",
    "V. Recognized as a single letter",
    "IV. Recognized as a roman numeral",
    "* Item 1\n\n  * Nested 1\n  * Nested 2\n\n* Item 2",
    "1. First\n\n   a. Sub-item\n   b. Sub-item\n\n2. Second",
    "Term\n    Definition of the term",
    "Term 1\n    Definition 1\nTerm 2\n    Definition 2",
    "Term 1\n    Definition 1\n\nTerm 2\n    Definition 2",
    ":field: value",
    ":field name: field value",
    ":field name: field value\n    continued",
    ":field name:\n    field value\n    continued",
    ":field 1: value 1\n:field 2: value 2",
    ":Field\\: X: Content",
    ":Field `foo-bar`:code:: Content",
    ":Not a field :code:`foo-bar`: Content",
    "   This is a block quote",
    "   Block quote line 1\n   Block quote line 2",
    "   Block quote line 1\n\n   Block quote line 2",
    "* List item.\n..\n    Block quote.| Line 1\n| Line 2\n| Line 3",
    "| Verse line 1\n|     Indented line 2",
    "| Line 1\n|     Indented\n|         More indented\n| Back to normal",
    "| Line 1\n  continues\n continues 2",
    "Example::\n\n    def foo():\n        pass",
    "::\n\n    x = 1\n    y = 2",
    "Example::\n\n> Line 1\n> Line 2",
    "::\n\n> Line 1\n> Line 2",
    ">>> print('hello')\nhello",
    ">>> x = 1\n>>> x + 1\n2",
    ">>> x = 1\n... x + 1\n2",
    "This is *emphasized* text",
    "*emphasis* at start",
    "end with *emphasis*",
    "Multiple *emphasis* and *more*",
    "This is **strong** text",
    "**strong** at start",
    "Multiple **strong** and **more**",
    "Use ``code`` for literals",
    "``x = 1`` is code",
    "Reference `something`",
    "Use `this` and `that`",
    ":code:`x = 1`",
    ":flag:`--verbose`",
    ":py:class:`MyClass`",
    ":py:class:`module.MyClass`",
    ":py:class:`~module.MyClass`",
    ":py:class:`Custom title <module.MyClass>`",
    "`Link text <https://example.com>`_",
    "`Foo <https://example.com>`_ and Foo_",
    "See `section`_\n\n.. _section: https://example.com",
    "`Custom title <target>`_\n\n.. _target: https://example.com",
    "__ https://example.com/1\n\n`Link 1`__\n`Link 2`__\n\n__ https://example.com/2",
    "`Custom title <target_>`_\n\n.. _target: https://example.com",
    ".. _target1: target2_\n.. _target2: https://example.com\n\ntarget1_",
    ".. _target1: target2_\n.. _target2: https://example.com\\_\n\ntarget1_",
    ".. _target1:\n.. _target2:\n.. _target3: https://example.com\n\ntarget1_ target2_ target3_",
    "Text [1]_ with footnote.\n\n.. [1] Footnote content",
    "Multiple [1]_ and [2]_ footnotes.\n\n.. [1] First\n.. [2] Second",
    "Text [#]_ with auto.\n\n.. [#] Auto footnote",
    "Text [#label]_ with label.\n\n.. [#label] Labeled auto",
    "Text [*]_ with symbol.\n\n.. [*] Symbol footnote",
    "Text [*]_ with [*]_ symbol.\n\n.. [*] Symbol footnote\n.. [*] Symbol footnote 2",
    "2 * x a ** b (* BOM32_* ` `` _ __ | (breaks rule 1)",
    "|| (breaks rule 3)",
    "\"*\" '|' (*) [*] {*} <*> “*” »*« ›*‹ «*» »*» ›*› (breaks rule 5)",
    "2*x a**b O(N**2) e**(x*y) f(x)*f(y) a|b file*.* __init__ __init__() (breaks rule 6)",
    "Style: *em*, **strong**, ***strong, with stars***, *broken `em`.",
    "Implicit ref: `something`, `a\\` b`. Broken: `something",
    "Explicit ref: :role:`ref`. Broken: :role:`ref",
    "Lua ref: :lua:obj:`a.b.c`, :lua:obj:`~a.b.c`, :lua:obj:`title <a.b.c>`.",
    "Code block: ``code``, ``code `backticks```,",
    "``escapes don't work here\\``, ``{ 1, 2, nil, 4 }``.",
    "Broken code block: ``foo *bar*",
    "Implicit hyperlinks: target_, anonymous__, not a link___.",
    "Explicit hyperlinks: `target`_, `anonymous`__.",
    "Malformed ref: :lua:obj:`~a.b.c`__ (still parsed as ref).",
    "Hyperlink: `foo bar`_, `foo bar`__, `foo <bar>`_.",
    "Internal hyperlink: _`foo bar`. Broken _`foo bar",
    "Footnote: [1]_, [2], [3",
    "Replacement: |foo|, |bar|_, |baz|__.",
    "*2 * x  *a **b *.rst*",
    "*2*x a**b O(N**2) e**(x*y) f(x)*f(y) a*(1+2)*",
    ".. code-block:: python\n\n   def foo():\n       pass",
    ".. code:: javascript\n\n   console.log('hello');",
    ".. note::\n\n   This is a note",
    ".. warning::\n\n   Be careful!",
    ".. tip:: Quick tip\n\n   Tip content",
    ".. attention:: Pay attention",
    ".. caution:: Be cautious",
    ".. danger:: Dangerous!",
    ".. error:: An error occurred",
    ".. hint:: A helpful hint",
    ".. important:: Important info",
    ".. seealso:: See also this",
    ".. versionadded:: 1.0\n\n   Added this feature",
    ".. versionchanged:: 2.0\n\n   Changed behavior",
    ".. deprecated:: 3.0\n\n   Use something else",
    ".. This is a comment",
    ".. Multi-line\n   comment",
    "..\n   Multi-line\n   comment",
    "..\n   Multi-line\n\n   comment",
    "Text with |substitution| reference",
    "----",
    "****",
    "====",
    "Before\n\n----\n\nAfter",
    "Escaped \\*not emphasized\\*",
    "Literal \\`backtick",
    "Backslash\\\\",
    "\n\nParagraph\n\n\n",
    "   Text with leading spaces",
    "Text with trailing spaces   ",
    "Title\n=====\n\n* List item\n\n  Paragraph in list\n\n  * Nested item\n\n* Back to top level",
    ".. code-block:: python\n   :linenos:\n\n   def foo():\n       pass",
    ".. admonition:: Custom Title\n\n   Note content here",
    "Term\n    First paragraph\n\n    Second paragraph",
    "Text [1]_\n\n.. [1] First para\n\n   Second para",
    "* Bullet\n* Items\n\n1. Numbered\n2. Items",
    ".. _target1: target2_\n.. _target2: target3_\n.. _target3: https://example.com\n\ntarget1_",
    ".. _target1: target2_\n.. _target2: target1_\n\ntarget1_",
    "Undefined footnotes: [#]_, [*]_",
    ">>> print(a)\na\n\n>>> print(b)\nb",
    ".. |subst| ...",
    ".. _target1:\n\nParagraph\n\n.. _target2: https://example.com\n\ntarget1_ target2_",
    "(1. not a list",
    "AA. not a list",
    "aa. not a list",
    "`empty explicit role`:: continues",
    "::`empty explicit role`",
    ":a+b:`explicit role with punct`",
    "`explicit role with punct`:a+b:",
    "empty interpreted text: :role:``",
    "`interpreted text(`)",
    "`interpreted text`___",
]


@pytest.mark.parametrize(
    "src",
    TEST_CASES,
    ids=[f"test-{i}" for i in range(len(TEST_CASES))],
)
def test_ast(src, file_regression):
    ast = yuio.rst.RstParser().parse(src)
    file_regression.check(f"{src}\n\n----------\n\n{ast.dump()}\n", encoding="utf-8")
