"""this contains the template-specific entities' classes"""

__docformat__ = "restructuredtext en"

from logilab.common.date import todate

from cubicweb.predicates import is_instance
from cubicweb.entities import AnyEntity, adapters, fetch_config
from cubicweb.entities.authobjs import CWUser
from cubicweb.web.views.calendar import ICalendarableAdapter
from cubicweb.web.views.ibreadcrumbs import IBreadCrumbsAdapter
from cubicweb.view import EntityAdapter

# cwuser

class ConferenceCWUser(CWUser):

    def dc_long_title(self):
        name = super(ConferenceCWUser, self).name()
        if self.representing:
            return u'%s (%s)' % (name, self.representing)
        else:
            return name

# conference

class Conference(AnyEntity):
    __regid__ = 'Conference'

    rest_attr = 'url_id'

    def dc_long_title(self):
        if self.start_on.month == self.end_on.month:
            dates = u'%s %s-%s' % (self.start_on.strftime('%B'), self.start_on.day, self.end_on.day)
        else:
            dates = u'%s - %s' % (self.start_on.strftime('%B %d'), self.end_on.strftime('%B %d'))
        city = self.take_place_at[0].city
        return u'%s - %s %s' % (self.title, dates, city)

    def get_talks_by_track(self, track):
        rql = 'Any T WHERE T in_track TR, TR eid %(tr)s'
        return self._cw.execute(rql, {'tr': track.eid})

    def has_talk(self, day, track):
        for talk in self.get_talks_by_track(track).entities():
            if talk.is_on_day(day):
                return True
        return False

class ConferenceITreeAdapter(adapters.ITreeAdapter):
    __select__ = is_instance('Conference')

    tree_relation = 'in_conf'

class ConferenceIBreadCrumbsAdapter(IBreadCrumbsAdapter):
    __select__ = is_instance('Conference')

    def breadcrumbs(self, view=None, recurs=False):
        return [(self.entity.absolute_url(), self.entity.dc_title())]

# track

class Track(AnyEntity):
    __regid__ = 'Track'
    fetch_attrs, cw_fetch_order = fetch_config(['title'])

class TrackICalendarableAdapter(ICalendarableAdapter):
    __select__ = is_instance('Track')

    @property
    def start(self):
        rql_date = ("Any MIN(ST) WHERE T eid %(track)s, X in_track T,"
                    "X start_time ST, X in_state S, S name 'accepted'")
        rset = self._cw.execute(rql_date, {"track": self.entity.eid})
        # Aggregate function can return None (#1381429)
        if len(rset) and rset[0][0] is not None:
            return rset[0][0]

    @property
    def stop(self):
        rql_date = ("Any MAX(ET) WHERE T eid %(track)s, X in_track T,"
                    "X end_time ET, X in_state S, S name 'accepted'")
        rset = self._cw.execute(rql_date, {"track": self.entity.eid})
        # Aggregate function can return None (#1381429)
        if len(rset) and rset[0][0] is not None:
            return rset[0][0]

class TrackITreeAdapter(adapters.ITreeAdapter):
    __select__ = is_instance('Track')

    tree_relation = 'in_track'

class TrackIBreadCrumbsAdapter(IBreadCrumbsAdapter):
    __select__ = is_instance('Track')

    def breadcrumbs(self, view=None, recurs=False):
        breadcrumbs = []
        if self.entity.in_conf:
            breadcrumbs = self.entity.in_conf[0].cw_adapt_to('IBreadCrumbs').breadcrumbs(view, True)
        breadcrumbs.append(self.entity)
        return breadcrumbs

# talk

class Talk(AnyEntity):
    __regid__ = 'Talk'
    fetch_attrs, cw_fetch_order = fetch_config(['start_time', 'end_time'])

    def is_on_day(self, day):
        date = todate(day)
        if self.start_time:
            talk_date = todate(self.start_time)
            return date == talk_date
        else:
            return False

    @property
    def track(self):
        # track is not mandatory in schema by default
        if self.in_track:
            return self.in_track[0]


class TalkIBreadCrumbsAdapter(IBreadCrumbsAdapter):
    __select__ = is_instance('Talk')

    def breadcrumbs(self, view=None, recurs=False):
        try:
            breadcrumbs = self.entity.in_track[0].cw_adapt_to('IBreadCrumbs').breadcrumbs(view, True)
        except IndexError:
            breadcrumbs = []
        breadcrumbs.append(self.entity)
        return breadcrumbs

class TalkICalendarableAdapter(EntityAdapter):
    __regid__ = 'ICalendarable'
    __select__ = is_instance('Talk')

    @property
    def start(self):
        return self.entity.start_time

    @property
    def stop(self):
        return self.entity.end_time
