"""Cataloging and searching components for students.
"""
import grok
from grok import index
from hurry.query import Eq, Text
from hurry.query.query import Query
from zope.catalog.interfaces import ICatalog
from zope.component import queryUtility
from waeup.sirp.interfaces import IUniversity, IQueryResultItem
from waeup.sirp.students.interfaces import IStudent

class StudentIndexes(grok.Indexes):
    """A catalog for students.
    """
    grok.site(IUniversity)
    grok.name('students_catalog')
    grok.context(IStudent)

    student_id = index.Field(attribute='student_id')
    fullname = index.Text(attribute='fullname')
    reg_number = index.Field(attribute='reg_number')
    matric_number = index.Field(attribute='matric_number')
    state = index.Field(attribute='state')
    certificate = index.Field(attribute='certificate')
    current_session = index.Field(attribute='current_session')

class StudentQueryResultItem(object):
    grok.implements(IQueryResultItem)

    title = u'Student Query Item'
    description = u'Some student found in a search'

    def __init__(self, context, view):
        self.context = context
        self.url = view.url(context)
        self.student_id = context.student_id
        self.fullname = context.fullname
        self.reg_number = context.reg_number
        self.matric_number = context.matric_number
        self.state = context.state

def search(query=None, searchtype=None, view=None):
    hitlist = []
    if searchtype in ('fullname',):
        results = Query().searchResults(
            Text(('students_catalog', searchtype), query))
    else:
        # Temporary solution to display all students added
        if query == '*':
            cat = queryUtility(ICatalog, name='students_catalog')
            results = cat.searchResults(student_id=(None, None))
        else:
            results = Query().searchResults(
                Eq(('students_catalog', searchtype), query))
    for result in results:
        hitlist.append(StudentQueryResultItem(result, view=view))
    return hitlist

class SimpleFieldSearch(object):
    """A programmatic (no UI required) search.

    Looks up a given field attribute of the students catalog for a
    single value. So normally you would call an instance of this
    search like this:

      >>> SimpleFieldSearch()(reg_number='somevalue')

    """
    catalog_name = 'students_catalog'
    def __call__(self, **kw):
        """Search students catalog programmatically.
        """
        if len(kw) != 1:
            raise ValueError('must give exactly one index name to search')
        cat = queryUtility(ICatalog, name=self.catalog_name)
        index_name, query_term = kw.items()[0]
        results = cat.searchResults(index_name=(query_term, query_term))
        return results

#: an instance of `SimpleFieldSearch` looking up students catalog.
simple_search = SimpleFieldSearch()
