#!/usr/bin/env python
# --!-- coding: utf8 --!--

from PyQt5.QtWidgets import qApp, QMessageBox
from manuskript.models import outlineItem
from manuskript.enums import Outline
from lxml import etree as ET
from manuskript.functions import mainWindow
from manuskript.importer.abstractImporter import abstractImporter

class opmlImporter(abstractImporter):

    name = "OPML"
    description = ""
    fileFormat = "OPML Files (*.opml *.xml)"
    icon = "text-x-opml+xml"

    @classmethod
    def isValid(cls):
        return True

    @classmethod
    def startImport(cls, filePath, parentItem, settingsWidget, fromString=None):
        """
        Import/export outline cards in OPML format.
        """
        ret = False

        if filePath != "":
            # We have a filePath, so we read the file
            try:
                with open(filePath, 'rb') as opmlFile:
                    #opmlContent = cls.saveNewlines(opmlFile.read())
                    opmlContent = opmlFile.read()
            except:
                QMessageBox.critical(settingsWidget,
                                    qApp.translate("Import", "OPML Import"),
                                    qApp.translate("Import", "File open failed."))
                return None

        elif fromString == "":
            # We have neither filePath nor fromString, so we leave
            return None

        else:
            # We load from string
            opmlContent = bytes(fromString, "utf-8")

        parsed = ET.fromstring(opmlContent)

        opmlNode = parsed
        bodyNode = opmlNode.find("body")
        items = []

        if bodyNode is not None:
            outlineEls = bodyNode.findall("outline")

            if outlineEls is not None:
                for element in outlineEls:
                    items.extend(cls.parseItems(element, parentItem))
                ret = True

        if not ret:
            QMessageBox.critical(
                settingsWidget,
                qApp.translate("Import", "OPML Import"),
                qApp.translate("Import", "This does not appear to be a valid OPML file."))

            return None

        return items

    @classmethod
    def parseItems(cls, underElement, parentItem=None):
        items = []
        title = underElement.get('text')
        if title is not None:

            card = outlineItem(parent=parentItem, title=title)
            items.append(card)

            body = ""
            note = underElement.get('_note')
            if note is not None and not cls.isWhitespaceOnly(note):
                #body = cls.restoreNewLines(note)
                body = note

            children = underElement.findall('outline')
            if children is not None and len(children) > 0:
                for el in children:
                    items.extend(cls.parseItems(el, card))
            else:
                card.setData(Outline.type, 'md')
                card.setData(Outline.text, body)

        return items

    @classmethod
    def saveNewlines(cls, inString):
        """
        Since XML parsers are notorious for stripping out significant newlines,
        save them in a form we can restore after the parse.
        """
        inString = inString.replace("\r\n", "\n")
        inString = inString.replace("\n", "{{lf}}")

        return inString

    @classmethod
    def restoreNewLines(cls, inString):
        """
        Restore any significant newlines
        """
        return inString.replace("{{lf}}", "\n")

    @classmethod
    def isWhitespaceOnly(cls, inString):
        """
        Determine whether or not a string only contains whitespace.
        """
        s = cls.restoreNewLines(inString)
        s = ''.join(s.split())

        return len(s) is 0
