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

################################################################
# zopyx.plone.smashdocs
# (C) 2016,  Andreas Jung, www.zopyx.com, Tuebingen, Germany
################################################################

import os
import zipfile
import tempfile
import mimetypes
import pkg_resources

import plone.api
from zope.interface import alsoProvides
from plone.protect.interfaces import IDisableCSRFProtection
from plone import namedfile
from plone.app.textfield.value import RichTextValue
from Products.CMFPlone.utils import safe_unicode
from pp.client.plone.browser.pdf import ProducePublishView

from zopyx.smashdocs.sdxml2html import sdxml2html
from .smashdocument import SmashDocument


class Converters(SmashDocument):

    def __init__(self, context, request):
        super(Converters, self).__init__(context, request)
        alsoProvides(self.request, IDisableCSRFProtection)

    def asHTML(self):
        """ Produce & Publish callback """
        obj = self.context['sdxml']['index.html']
        return obj.text.output

    def store_as_file(self, fn, obj_id, container=None, delete=True):
        """ Store binary content of `out_fn` as Plone 'File' object """

        if not container:
            container = self.context
        if obj_id in container.objectIds():
            plone.api.content.delete(container[obj_id])
        obj = plone.api.content.create(
            type='File',
            id=obj_id,
            title=obj_id,
            container=container)
        mt, _ = mimetypes.guess_type(obj_id)
        with open(fn, 'rb') as fp:
            obj.file = namedfile.NamedBlobImage(
                fp.read(),
                filename=unicode(obj_id),
                contentType=mt)
        if delete:
            os.unlink(fn)

    def convert_docx(self):
        sd = self.smashdocs
        templates = sd.list_templates()
        out_fn = sd.export_document(
            document_id=self.context.document_id,
            format='docx',
            user_id=self.user_id,
            template_id=templates[0]['id'])
        self.store_as_file(out_fn, 'index.docx')
        return self.request.response.redirect(self.context.absolute_url())

    def convert_sdxml(self):
        sd = self.smashdocs
        out_fn = sd.export_document(
            document_id=self.context.document_id,
            format='sdxml',
            user_id=self.user_id)
        self.store_as_file(out_fn, 'index_sdxml.zip', delete=False)
        self.unpack_zip(out_fn, 'sdxml')
        return self.request.response.redirect(self.context.absolute_url())

    def convert_pdf(self):
        view = ProducePublishView(self.context, self.request)
        out_fn = view()
        self.store_as_file(out_fn, 'index.pdf')
        return self.request.response.redirect(self.context.absolute_url())

    def convert_epub(self):
        view = ProducePublishView(self.context, self.request)
        out_fn = view()
        self.store_as_file(out_fn, 'index.epub')
        return self.request.response.redirect(self.context.absolute_url())

    def convert_html(self):

        sd = self.smashdocs

        out_fn = sd.export_document(
            document_id=self.context.document_id,
            format='html',
            user_id=self.user_id)

        if 'index_html.zip' in self.context.objectIds():
            plone.api.content.delete(self.context['index_html.zip'])

        obj = plone.api.content.create(
            type='File',
            id='index_html.zip',
            title='index_html.zip',
            container=self.context)

        with open(out_fn, 'rb') as fp:
            obj.file = namedfile.NamedBlobImage(
                fp.read(),
                filename=u'index_html.zip',
                contentType='application/zip')

        # unpack packed HTML ZIP file

        # create 'html' subfolder
        if 'html' in self.context.objectIds():
            plone.api.content.delete(self.context['html'])
        folder = plone.api.content.create(
            container=self.context,
            type='Folder',
            id='html',
            title='html')

        # create 'images' subfolder
        plone.api.content.create(
            container=folder,
            type='Folder',
            id='images',
            title='images')

        # unpack ZIP file
        self.unpack_zip(out_fn, 'html')

        os.unlink(out_fn)
        return self.request.response.redirect(self.context.absolute_url())

    def unpack_zip(self, zip_fn, folder_id):

        if folder_id in self.context.objectIds():
            plone.api.content.delete(self.context[folder_id])

        folder = plone.api.content.create(
            type='Folder',
            container=self.context,
            id=folder_id,
            title=folder_id)

        images = plone.api.content.create(
            type='Folder',
            container=folder,
            id='images',
            title='images')

        with zipfile.ZipFile(zip_fn, 'r') as zf:
            for name in zf.namelist():
                data = zf.read(name)
                if name == 'index.html':
                    obj = plone.api.content.create(
                        type='Document',
                        container=folder,
                        title=name,
                        id=name)
                    obj.text = RichTextValue(data, 'text/html', 'text/html')
                elif name == 'sd.xml':
                    obj = plone.api.content.create(
                        type='File',
                        container=folder,
                        title=name,
                        id=name)
                    obj.file = namedfile.NamedBlobImage(
                        data,
                        filename=u'sd.xml',
                        contentType='text/xml')

                    xml_tmp = tempfile.mktemp(suffix='.xml')
                    with open(xml_tmp, 'wb') as fp:
                        fp.write(data)

                    out_fn = sdxml2html.sdxml2html(xml_tmp)
                    with open(out_fn, 'rb') as fp:
                        html = fp.read()
                    os.unlink(xml_tmp)
                    os.unlink(out_fn)
                    obj = plone.api.content.create(
                        type='Document',
                        container=folder,
                        title='index.html',
                        id='index.html')
                    obj.text = RichTextValue(html, 'text/html', 'text/html')
                    obj = plone.api.content.create(
                        type='File',
                        container=folder,
                        title='styles.css',
                        id='styles.css')
                    styles = pkg_resources.resource_string(
                        'zopyx.smashdocs.sdxml2html', 'styles.css')
                    obj.file = namedfile.NamedBlobImage(
                        styles,
                        filename=u'styles.css',
                        contentType='text/css')

                else:
                    basename = os.path.basename(name)
                    obj = plone.api.content.create(
                        type='Image',
                        id=basename,
                        title=basename,
                        container=images)
                    obj.image = namedfile.NamedBlobImage(
                        data,
                        filename=safe_unicode(basename),
                        contentType='image/png')
