# -*- coding: utf-8 -*-

"""
This program receive a xml file name as input parameter.
The xml file is parsed to extract significant data to process the contained passive documents from a Cobol applications.
Plus in details, it will generates:
 - a xml smaller general document with witch is an index referencing the passive documents found into the input file;
 - a xml file for each passive document reporting its content cleaned by the attachments binary data
 - a binary file for each attachment extracted from the documents content
The name of the first file (the index) is received as second parameter
The xml files for contents end attachments are generated by the program as temporary files.
The names of the generated temporary files are reported into the index file.
"""

import sys
import os
import xml.etree.ElementTree as ET
import xml.dom.minidom as MD
import base64
import tempfile
import lxml.etree as LET
import pdfkit


# definisce il trasformatore dell'xml secondo il foglio di stile assosoftware
xslt = LET.parse(os.path.dirname(os.path.realpath(__file__)) + "/FoglioStileAssoSoftware.xsl")
transform = LET.XSLT(xslt)

inputfile = sys.argv[1]
outputfile = sys.argv[2]

itree = ET.parse(inputfile)
iroot = itree.getroot()

result = ET.Element('data')
resultItems = ET.SubElement(result, 'documenti')

body = iroot[0]
response = body[0]
documents = response[0]
for elem in documents:
    # dati di testata documento
    documento = elem[3]
    resultItem = ET.SubElement(resultItems, 'documento')
    resultHubID = ET.SubElement(resultItem, "hubID")
    resultHubID.text = documento[0].text
    # stati documento
    resultStati = ET.SubElement(resultItem, "stati")
    stati = elem[6][0][1]
    for stato in stati:
        resultStato = ET.SubElement(resultStati, "stato")
        resultTimestamp = ET.SubElement(resultStato, "timestamp")
        resultTimestamp.text = stato[0].text
        resultName = ET.SubElement(resultStato, "name")
        resultName.text = stato[1].text
    # decodifica il content da base64 a xml
    testo64 = base64.b64decode(elem[7].text.encode('ascii'))
    ixml = ET.fromstring(testo64)
    # in ixml abbiamo in mano l'xml della singola fattura
    # generiamo subito il documento applicando il foglio di stile AssoSoftware
    dom = LET.fromstring(testo64)
    newdom = transform(dom)
    tf = tempfile.NamedTemporaryFile(mode='w+b', delete=False)
    tf.close
    html = LET.tostring(newdom)
    pdf = pdfkit.from_string(html, tf.name)
    resultHTML = ET.SubElement(resultItem, "pdf")
    resultHTML.text = tf.name
    # lo svuotiamo da eventuali attachment che salviamo su file temporanei e al loro
    # posto lasciamo il nome del file salvato
    resultAllegati = ET.SubElement(resultItem, "allegati")
    for attach in ixml.iter('Allegati'):
        allegato = attach.find('Attachment')
        if allegato is not None and allegato.text is not None:
            # salva l'allegato su un file temporaneo
            tf = tempfile.NamedTemporaryFile(mode='w+b', delete=False)
            content = base64.b64decode(allegato.text.encode('ascii'))
            tf.write(content)
            tf.close
            # riporta il nome del file temporaneo contenente l'allegato nell'xml di result
            resultAllegato = ET.SubElement(resultAllegati, "allegato")
            resultFileName = ET.SubElement(resultAllegato, "filename")
            resultFileName.text = tf.name
            # riporta il tipo del file allegato nell'xml di result
            formato = attach.find('FormatoAttachment')
            if formato is not None and formato.text is not None:
                resultFormato = ET.SubElement(resultAllegato, "formato")
                resultFormato.text = formato.text.replace(".", "")
            # rimuove l'attachment dall'xml del documento per alleggerirlo e renderlo leggibile dal cobol
            attach.remove(allegato)
    # l'xml della fattura ripulito dagli attachment anch'esso viene salvato su un file temporaneo
    tf = tempfile.NamedTemporaryFile(mode='w+b', delete=False)
    mydata = ET.tostring(ixml)
    tf.write(mydata)
    tf.close
    # il nome dell'xml della fattura appena salvato lo riportiamo nell'xml di result
    resultContent = ET.SubElement(resultItem, "content")
    resultContent.text = tf.name

# l'xml principale risultante viene infine salvato
mydata = ET.tostring(result)
dom = MD.parseString(mydata)
pretty_xml = dom.toprettyxml()
myfile = open(outputfile, "w")
myfile.write(pretty_xml)
myfile.close


