"""Catalog and searching components for academics stuff.
"""
import grok
from hurry.query import Eq
try:
     from zope.catalog.interfaces import ICatalog
except ImportError:
     # BBB
     from zope.app.catalog.interfaces import ICatalog
from zope.component import getUtility
from zope.component.interfaces import ComponentLookupError
try:
     from zope.intid import IIntIds
except ImportError:
     # BBB
     from zope.app.intid.interfaces import IIntIds
from waeup.sirp.interfaces import IUniversity
from waeup.sirp.catalog import QueryResultItem
from waeup.sirp.university.interfaces import ICourse, ICertificateCourse

class CourseIndexes(grok.Indexes):
     grok.site(IUniversity)
     grok.name('courses_catalog')
     grok.context(ICourse)

     code = grok.index.Field(attribute='code')
     title = grok.index.Text(attribute='title')

class CourseCertificatesIndexes(grok.Indexes):
     grok.site(IUniversity)
     grok.name('certcourses_catalog')
     grok.context(ICertificateCourse)

     course_code = grok.index.Field(attribute='getCourseCode')

@grok.subscribe(ICourse, grok.IObjectAddedEvent)
def handleCourseAdd(obj, event):
     """Index an added course with the local catalog.

     Courses are not indexed automatically, as they are not a
     dictionary subitem of the accompanied site object
     (`IUniversity`). I.e. one cannot get them by asking for
     ``app['FACCODE']['DEPTCODE']['COURSECODE']`` but one has to ask for
     ``app.faculties['FACCODE']['DEPTCODE'].courses['COURSECODE']``.

     Once, a course is indexed we can leave the further handling to
     the default component architechture. At least removals will
     be handled correctly then (and the course unindexed).
     """
     try:
          cat = getUtility(ICatalog, name='courses_catalog')
     except ComponentLookupError:
          # catalog not available. This might happen during tests.
          return
     intids = getUtility(IIntIds)
     index = cat['code']
     index.index_doc(intids.getId(obj), obj)

class CourseQueryResultItem(QueryResultItem):
     def __init__(self, context, view):
          self.context = context
          self.url = view.url(context)
          self.title = "COURSE: " + context.title
          self.description = 'code: %s' % context.code

def search(query=None, view=None):
     if not query:
          return []
     cat = getUtility(ICatalog, name='courses_catalog')
     results = list(cat.searchResults(code=(query, query)))
          
     hitlist = []
     results = Query().searchResults(
          Eq(('courses_catalog', 'code'), query))
     for result in results:
          hitlist.append(CourseQueryResultItem(result, view=view))

     results = Query().searchResults(
          Text(('courses_catalog', 'title'), query))
          
     for result in results:
          hitlist.append(CourseQueryResultItem(result, view=view))

     return hitlist
