import sys
from pathlib import Path

from .codeeditor import _make_textformats
from ..Qt import QtWidgets, QtCore, QtGui
from nmreval.configs import config_paths


STYLES = {'INFO': _make_textformats('black'),
          'WARNING': _make_textformats('blue'),
          'ERROR': _make_textformats('red', 'bold'),
          'DEBUG': _make_textformats('black', 'italic'),
          'file': _make_textformats('red', 'italic'),
          'PyError': _make_textformats('red', 'bold-italic')}


class LogHighlighter(QtGui.QSyntaxHighlighter):
    msg = ['INFO', 'DEBUG', 'ERROR', 'WARNING']

    def __init__(self, parent):
        super(LogHighlighter, self).__init__(parent)

        rules = list()
        rules += [(r'\b\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2} - %s - .*' % m, 0, STYLES[m]) for m in LogHighlighter.msg]
        rules += [(r'\b[A-Z]\w*Error: .*\b', 0, STYLES['PyError'])]
        rules += [(r'\bFile .*', 0, STYLES['file'])]

        self.rules = [(QtCore.QRegExp(pat), index, fmt) for (pat, index, fmt) in rules]

    def highlightBlock(self, text):
        """Apply syntax highlighting to the given block of text.
        """
        # Do other syntax formatting
        for expression, nth, format in self.rules:
            index = expression.indexIn(text, 0)

            while index >= 0:
                # We actually want the index of the nth match
                index = expression.pos(nth)
                try:
                    length = expression.cap(nth).length()
                except AttributeError:
                    length = len(expression.cap(nth))
                self.setFormat(index, length, format)
                index = expression.indexIn(text, index + length)

        self.setCurrentBlockState(0)

    def match_multiline(self, text, delimiter, in_state, style):
        if self.previousBlockState() == in_state:
            start = 0
            add = 0
        else:
            start = delimiter.indexIn(text)
            add = delimiter.matchedLength()

        while start >= 0:
            end = delimiter.indexIn(text, start + add)
            if end >= add:
                length = end - start + add + delimiter.matchedLength()
                self.setCurrentBlockState(0)
            else:
                self.setCurrentBlockState(in_state)
                try:
                    length = text.length() - start + add
                except AttributeError:
                    length = len(text) - start + add
            # Apply formatting
            self.setFormat(start, length, style)
            # Look for the next match
            start = delimiter.indexIn(text, start + length)

        # Return True if still inside a multi-line string, False otherwise
        if self.currentBlockState() == in_state:
            return True
        else:
            return False


class QLog(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(QLog, self).__init__(parent=parent)

        self._initUi()

        self.logfile = config_paths() / 'errors.log'

        self.read_log()

    def _initUi(self):

        self.resize(960, 640)
        layout = QtWidgets.QVBoxLayout()
        self.plainTextEdit = QtWidgets.QPlainTextEdit()
        self.plainTextEdit.highlight = LogHighlighter(self.plainTextEdit.document())
        self.plainTextEdit.setReadOnly(True)
        self.plainTextEdit.setMaximumBlockCount(50)
        layout.addWidget(self.plainTextEdit)

        self.buttonBox = QtWidgets.QDialogButtonBox()
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        layout.addWidget(self.buttonBox)

        self.setLayout(layout)

    def read_log(self):
        with Path(self.logfile).open('r') as f:
            text = f.readlines()

        for lines in text[-100:]:
            self.plainTextEdit.appendPlainText(lines[:-1])
