from plone.memoize.view import memoize
from plone.rfc822.interfaces import IPrimaryFieldInfo
from ploneintranet import api as pi_api
from Products.Five import BrowserView
from zope.datetime import rfc1123_date


class PdfView(BrowserView):
    def get_pdf(self):
        pdf = pi_api.previews.get_pdf(self.context)
        if not pdf:
            return
        with pdf.open() as fh:
            return fh.read()

    @memoize
    def has_pdf(self):
        return pi_api.previews.has_pdf(self.context)

    @property
    @memoize
    def timestamp(self):
        """Return the modification time of document pdf representation.

        If the document has a pdf preview,
        return the modification time of the blob.

        If the document has no pdf preview,
        return the modification time of the document primary field.

        As a fallback, return the modification time of the document itself.
        """
        try:
            return pi_api.previews.get_pdf(self.context)._p_mtime
        except AttributeError:
            pass

        try:
            return IPrimaryFieldInfo(self.context).value._p_mtime
        except (AttributeError, TypeError):
            pass

        return self.context._p_mtime

    def __call__(self):
        if not self.has_pdf():
            return self.request.RESPONSE.redirect(
                self.context.absolute_url() + "/pdf-not-available"
            )

        data = self.get_pdf()
        if not data:
            # Conversion failed. What to do?
            # A proper error message would be in order.
            self.request.response.setBody(
                "<h1>404 Not Found</h1><p>PDF preview not available</p>"
            )
            return self.request.response.setStatus(404)

        length = len(data)
        self.request.response.setHeader(
            "Last-Modified", rfc1123_date(self.context._p_mtime)
        )
        for_print = self.request.form.get("for_print", False)
        if not for_print:
            self.request.response.setHeader(
                "content-disposition",
                'attachment; filename="%s"' % ".".join((self.context.getId(), "pdf")),
            )
        self.request.response.setHeader("Accept-Ranges", "bytes")
        self.request.response.setHeader("Content-Length", length)
        self.request.response.setHeader("Content-Type", "application/pdf")

        return data
