import xml.dom
from typing import List, Optional

from .exporter import exporter_mult

# Base XML exporter class


class XmlExporter(exporter_mult):

    # doc_element = 'rec'
    # doctype_desc = ''
    # dtd_path = ''

    def __init__(self, rd, r, out, order: Optional[List[str]] = None, xmlDoc=None, **kwargs):
        order = order or ["attr", "image", "ings", "text"]
        if xmlDoc:
            self.xmlDoc = xmlDoc
            self.i_created_this_document = False
            self.top_element = self.xmlDoc.childNodes[1]
        else:
            self.create_xmldoc()
        exporter_mult.__init__(self, rd, r, out, use_ml=True, convert_attnames=False, do_markup=True, order=order, **kwargs)

    def create_xmldoc(self):
        self.i_created_this_document = True
        impl = xml.dom.getDOMImplementation()
        doctype = impl.createDocumentType(self.doc_element, self.doctype_desc, self.dtd_path)
        self.xmlDoc = impl.createDocument(None, self.doc_element, doctype)
        self.top_element = self.xmlDoc.documentElement

    # Convenience methods
    def set_attribute(self, element, attribute, value):
        a = self.xmlDoc.createAttribute(attribute)
        element.setAttributeNode(a)
        element.setAttribute(attribute, value)

    def append_text(self, element, text):
        try:
            assert isinstance(text, str)
        except AssertionError:
            print("Text is not text")
            print("append_text received", element, text)
            raise TypeError("%r is not a StringType" % text)
        try:
            t = self.xmlDoc.createTextNode(text)
            element.appendChild(t)
        except Exception as e:
            print("FAILED WHILE WORKING ON ", element)
            print("TRYING TO APPEND", text[:100])
            raise e

    def create_text_element(self, element_name, text, attrs={}):
        element = self.create_element_with_attrs(element_name, attrs)
        self.append_text(element, text)
        return element

    def create_element_with_attrs(self, element_name, attdic):
        element = self.xmlDoc.createElement(element_name)
        for k, v in list(attdic.items()):
            self.set_attribute(element, k, str(v))
        return element
