"""cube-specific forms/views/actions/components

Specific views for cards

:organization: Logilab
:copyright: 2001-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""
__docformat__ = "restructuredtext en"

from cubicweb import _


from logilab.mtconverter import xml_escape
from logilab.common.decorators import cachedproperty

from cubicweb.predicates import is_instance, match_form_params
from cubicweb_web.views import uicfg, primary, baseviews
from cubicweb_web.views.autoform import AutomaticEntityForm
from cubicweb_web.views.ibreadcrumbs import IBreadCrumbsAdapter

uicfg.primaryview_section.tag_attribute(("Card", "title"), "hidden")
uicfg.primaryview_section.tag_attribute(("Card", "synopsis"), "hidden")
uicfg.primaryview_section.tag_attribute(("Card", "wikiid"), "hidden")


class CardPrimaryView(primary.PrimaryView):
    __select__ = is_instance("Card")
    show_attr_label = False

    def render_entity_title(self, entity):
        self.w(f"<h1>{xml_escape(entity.title)}</h1>")
        if entity.synopsis:
            self.w(f"<div class=\"summary\">{entity.printable_value('synopsis')}</div>")


class CardInlinedView(CardPrimaryView):
    """hide card title and summary"""

    __regid__ = "inlined"
    title = _("inlined view")
    main_related_section = False

    def render_entity_title(self, entity):
        self.w(f"<div class=\"summary\">{entity.printable_value('synopsis')}</div>")

    def content_navigation_components(self, context):
        pass


class CardDoesNotExistView(baseviews.NoResultView):
    __select__ = baseviews.NoResultView.__select__ & match_form_params("wikiid")

    def call(self, **kwargs):
        super().call(**kwargs)
        etype = self._cw.vreg["etypes"].etype_class("Card")
        ctx = {
            "url": etype.cw_create_url(self._cw, wikiid=self._cw.form["wikiid"]),
            "message": xml_escape(self._cw._("This card does not exist yet.")),
            "invite": xml_escape(self._cw._("Create it?")),
            "notice": "",
        }
        if not self._cw.vreg.schema["Card"].has_perm(self._cw, "add"):
            ctx["notice"] = xml_escape(self._cw._(" (You may need to log in first.)"))
        self.w(
            '<div class="section">%(message)s '
            '<a href="%(url)s">%(invite)s</a>%(notice)s</div>' % ctx
        )
        self._cw.status_out = 404


class CardBreadCrumbsAdapter(IBreadCrumbsAdapter):
    __select__ = IBreadCrumbsAdapter.__select__ & is_instance("Card")

    @cachedproperty
    def dirname(self):
        if self.entity.wikiid:
            return "/".join(self.entity.wikiid.split("/")[:-1])

    def card_from_wikiid(self, path):
        """Return the Card given its ``wikiid`` path or None"""
        rset = self._cw.execute("Card C WHERE C wikiid %(id)s", {"id": path})
        if rset:
            return rset.get_entity(0, 0)

    def parent_entity(self):
        if not self.dirname:
            # card is at root: return whatever super returns
            parent = super().parent_entity()
        else:
            parent = self.card_from_wikiid(self.dirname)
        return parent

    def breadcrumbs(self, view=None, recurs=None):
        """Virtual hierarchy of wiki pages following a directory-like
        structure.
        """
        if self.parent_entity() or not self.dirname:
            # parent Card exists or the current Card is at the root (i.e. its
            # wikiid has no /)
            return super().breadcrumbs(view, recurs)
        else:
            # parent card does not exist: build the (reversed) path by
            # iterating on the directory structure
            path = [self.entity]
            dirs = self.dirname.split("/")
            while dirs:
                card = self.card_from_wikiid("/".join(dirs))
                p = [dirs.pop()]
                if card:
                    p = card.cw_adapt_to("IBreadCrumbs").breadcrumbs(view, recurs)
                path.extend(p)
            if not card:
                # last path entry is not a card
                path.append(
                    (
                        self._cw.build_url(str(self.entity.e_schema)),
                        self._cw._("Card_plural"),
                    )
                )
            path.reverse()
            return path


try:
    from cubicweb_seo.views import SitemapRule

    class CardSitemapRule(SitemapRule):
        __regid__ = "card"
        query = "Any X WHERE X is Card"
        priority = 1.0

except ImportError:
    pass


def registration_callback(vreg):
    vreg.register(CardPrimaryView)
    vreg.register(CardInlinedView)
    vreg.register(CardDoesNotExistView)
    vreg.register(CardBreadCrumbsAdapter)

    loaded_cubes = vreg.config.cubes()

    if "seo" in loaded_cubes:
        vreg.register(CardSitemapRule)

    if "preview" in loaded_cubes:
        from cubicweb_preview.views.forms import PreviewFormMixin

        class PreviewAutomaticEntityForm(PreviewFormMixin, AutomaticEntityForm):
            preview_mode = "inline"
            __select__ = AutomaticEntityForm.__select__ & is_instance("Card")

        vreg.register(PreviewAutomaticEntityForm)
