from __future__ import print_function

from lxml import etree
import emitter

class XMLEmitter(emitter.Emitter):
    def preface(self):
        return """<?xml version="1.0" encoding="utf-8"?>
<!-- Dynamically generated list of documented logfile messages (generated by parse.py) -->
"""

    def postface(self):
        return

    def start(self):
        self.logname = "LogMessages.xml"
        self.fh = open("LogMessages.xml", mode='w')
        print(self.preface(), file=self.fh)
        self.loggermessagefile = etree.Element('loggermessagefile')

    def emit(self, doccos, enumerations):
        self.start()
        for docco in doccos:
            xml_logformat = etree.SubElement(self.loggermessagefile, 'logformat', name=docco.name)
            if docco.url is not None:
                xml_url = etree.SubElement(xml_logformat, 'url')
                xml_url.text = docco.url
            if docco.description is not None:
                xml_description = etree.SubElement(xml_logformat, 'description')
                xml_description.text = docco.description

            xml_fields = etree.SubElement(xml_logformat, 'fields')
            for f in docco.fields_order:
                xml_field = etree.SubElement(xml_fields, 'field', name=f)
                if "description" in docco.fields[f]:
                    xml_description2 = etree.SubElement(xml_field, 'description')
                    xml_description2.text = docco.fields[f]["description"]
                if "bitmaskenum" in docco.fields[f]:
                    enum_name = docco.fields[f]["bitmaskenum"]
                    if enum_name not in enumerations:
                        raise Exception("Unknown enum (%s) (have %s)" %
                                        (enum_name, "\n".join(sorted(enumerations.keys()))))
                    bit_mask = enumerations[enum_name]
                    xml_bitmask = etree.SubElement(xml_field, 'bitmask')
                    for bit in bit_mask.entries:
                        xml_bitmask_bit = etree.SubElement(xml_bitmask, 'bit', name=bit.name)
                        xml_bitmask_bit_value = etree.SubElement(xml_bitmask_bit, 'value')
                        xml_bitmask_bit_value.text =  str(bit.value)
                        if bit.comment is not None:
                            xml_bitmask_bit_comment = etree.SubElement(xml_bitmask_bit, 'description')
                            xml_bitmask_bit_comment.text = bit.comment
            if xml_fields.text is None and not len(xml_fields):
                xml_fields.text = '\n'  # add </param> on next line in case of empty element.
        self.stop()

    def stop(self):
        # etree.indent(self.loggermessagefile)  # not available on thor, Ubuntu 16.04
        pretty_xml = etree.tostring(self.loggermessagefile, pretty_print=True, encoding='unicode')
        self.fh.write(pretty_xml)
        self.fh.close()