# -*- coding: utf-8 -*-
#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License

"""Tests for syntaxhighlighters.py"""

import pytest
from qtpy.QtWidgets import QApplication
from qtpy.QtGui import QTextDocument

from spyder.utils.syntaxhighlighters import HtmlSH, PythonSH, MarkdownSH

def compare_formats(actualFormats, expectedFormats, sh):
    assert len(actualFormats) == len(expectedFormats)
    for actual, expected in zip(actualFormats, expectedFormats):
        assert actual.start == expected[0]
        assert actual.length == expected[1]
        # compare formats by looking at foreground colours only
        assert (actual.format.foreground().color().name()
                == sh.formats[expected[2]].foreground().color().name())

def test_HtmlSH_basic():
    txt = '<p style="color:red;">Foo <!--comment--> bar.</p>'
    doc = QTextDocument(txt)
    sh = HtmlSH(doc, color_scheme='Spyder')
    sh.rehighlightBlock(doc.firstBlock())

    # Expected result as list of tuples (begin, length, format)
    res = [(0, 2, 'builtin'),    # |<p|
           (2, 6, 'keyword'),    # | style|
           (8, 1, 'normal'),     # | |
           (9, 12, 'string'),    # |"color:red;"|
           (21, 1, 'builtin'),   # |>|
           (22, 4, 'normal'),    # |Foo |
           (26, 14, 'comment'),  # |<!--comment-->|
           (40, 5, 'normal'),    # | bar.|
           (45, 4, 'builtin')]   # |</p>|
    compare_formats(doc.firstBlock().layout().formats(), res, sh)

def test_HtmlSH_unclosed_commend():
    txt = '-->'
    doc = QTextDocument(txt)
    sh = HtmlSH(doc, color_scheme='Spyder')
    sh.rehighlightBlock(doc.firstBlock())
    res = [(0, 3, 'normal')]
    compare_formats(doc.firstBlock().layout().formats(), res, sh)


def test_PythonSH_UTF16_number():
    """UTF16 string"""
    txt = '𨭎𨭎𨭎𨭎 = 100000000'
    doc = QTextDocument(txt)
    sh = PythonSH(doc, color_scheme='Spyder')
    sh.rehighlightBlock(doc.firstBlock())
    res = [(0, 11, 'normal'), (11, 9, 'number')]
    compare_formats(doc.firstBlock().layout().formats(), res, sh)


def test_PythonSH_UTF16_string():
    """UTF16 string"""
    txt = '𨭎𨭎𨭎𨭎 = "𨭎𨭎𨭎𨭎"'
    doc = QTextDocument(txt)
    sh = PythonSH(doc, color_scheme='Spyder')
    sh.rehighlightBlock(doc.firstBlock())
    res = [(0, 11, 'normal'), (11, 10, 'string')]
    compare_formats(doc.firstBlock().layout().formats(), res, sh)


def test_python_string_prefix():
    prefixes = ("r", "u", "R", "U", "f", "F", "fr", "Fr", "fR", "FR",
                "rf", "rF", "Rf", "RF", "b", "B", "br", "Br", "bR", "BR",
                "rb", "rB", "Rb", "RB")
    for prefix in prefixes:
        txt = "[%s'test', %s'''test''']" % (prefix, prefix)

        doc = QTextDocument(txt)
        sh = PythonSH(doc, color_scheme='Spyder')
        sh.rehighlightBlock(doc.firstBlock())

        offset = len(prefix)
        res = [(0, 1, 'normal'),                     # |[|
               (1, 6 + offset, 'string'),            # |{prefix}'test'|
               (7 + offset, 2, 'normal'),            # |, |
               (9 + offset, 10 + offset, 'string'),  # |{prefix}'''test'''|
               (19 + 2*offset, 1, 'normal')]         # | |

        compare_formats(doc.firstBlock().layout().formats(), res, sh)


def test_Markdown_basic():
    txt = "Some __random__ **text** with ~~different~~ [styles](link_url)"

    doc = QTextDocument(txt)
    sh = MarkdownSH(doc, color_scheme='Spyder')
    sh.rehighlightBlock(doc.firstBlock())

    res = [(0, 5, 'normal'),  # |Some|
           (5, 10, 'italic'),  # |__random__|
           (15, 1, 'normal'),  # | |
           (16, 8, 'strong'),  # |**text**|
           (24, 6, 'normal'),  # |with|
           (30, 13, 'italic'),  # |~~diferents~~|
           (43, 1, 'normal'),  # | |
           (44, 8, 'string'),  # |[styles]|
           (52, 1, 'normal'),  # |(|
           (53, 8, 'string'),  # |(link_url)|
           (61, 1, 'normal'),  # ||
           ]

    compare_formats(doc.firstBlock().layout().formats(), res, sh)


@pytest.mark.parametrize('line', ['# --- First variant',
                                  '#------ 2nd variant',
                                  '### 3rd variant'])
def test_python_outline_explorer_comment(line):
    assert PythonSH.OECOMMENT.match(line)

@pytest.mark.parametrize('line', ['#---', '#--------', '#---   ', '# -------'])
def test_python_not_an_outline_explorer_comment(line):
    assert not PythonSH.OECOMMENT.match(line)


if __name__ == '__main__':
    pytest.main()
