from plone import api
from ploneintranet import api as pi_api
from Products.Five.browser import BrowserView
from zExceptions import NotFound
from zope.interface import implementer
from zope.publisher.interfaces import IPublishTraverse


@implementer(IPublishTraverse)
class StandalonePost(BrowserView):
    """Registered as a browser view at '/@@post/'.

    Get statusupdate.id from the url, check security, and display the
    thread.

    For example, /@@post/12345 will display the full thread for the
    thread parent of the statusupdate with id 12345.

    Note that this is different from:

    - the various post views in ploneintranet.microblog that handle
    update creation

    - the various traverser views in ploneintranet.activitystream that
    handle inline display of statusupdates in the stream

    This view lives in microblog because it is coupled with the
    statusupdate, and can be used not only in notifications but also
    for rendering a post as a search result.
    """

    status_id = None

    def publishTraverse(self, request, name):
        self.status_id = name
        # stop traversing, we have arrived
        request["TraversalRequestNameStack"] = []
        # return self so the publisher calls this view
        return self

    @property
    def status_update(self):
        try:
            status_update = pi_api.microblog.statusupdate.get(self.status_id)
        except KeyError:
            # This shows a traceback. Can we do better?
            raise NotFound("Invalid statusupdate id")
        while status_update.parent:
            status_update = status_update.parent
        return status_update

    def render_post(self):
        """
        Delegate the inner rendering to activitystream provided inner view.
        """
        # BBB temporary backward compatibility for @@post?id=1234
        if not self.status_id:
            status_id = self.request.get("id")
            if status_id:
                return self.request.response.redirect(
                    f"{self.context.absolute_url()}/@@post/{status_id}"
                )

        # use same inner rendering as /statusupdate/12345/post.html, while
        # bypassing that traverser and avoiding a second statusupdate
        # database read
        inner_view = api.content.get_view("post.html", self.status_update, self.request)
        return inner_view()


class PostComments(StandalonePost):
    def __call__(self):
        return api.content.get_view("post-comments", self.status_update, self.request)()
