"""Course containers.
"""
import grok
from zope.interface import implementedBy
from zope.component.interfaces import IFactory, ComponentLookupError
from zope.catalog.interfaces import ICatalog
from zope.component import queryUtility
from waeup.sirp.interfaces import DuplicationError
from waeup.sirp.university.interfaces import ICourseContainer, ICourse

class CourseContainer(grok.Container):
    """See interfaces for description.
    """
    grok.implements(ICourseContainer)
    grok.require('waeup.manageUniversity')

    def __setitem__(self, name, course):
        """See corresponding docstring in certificatecontainer.py.
        """
        if not ICourse.providedBy(course):
            raise TypeError('CourseContainers contain only '
                            'ICourse instances')

        # Only accept courses with code == key.
        if course.code != name:
            raise ValueError('key must match course code: '
                             '%s, %s' % (name, course.code))

        # Lookup catalog. If we find none: no duplicates possible.
        cat = queryUtility(ICatalog, name='courses_catalog', default=None)
        if cat is not None:
            entries = cat.searchResults(
                code=(course.code,course.code))
            if len(entries) > 0:
                raise DuplicationError(
                    'Course exists already elsewhere.', entries)
        else:
            # No catalog, then this addition won't do harm to anything.
            pass
        super(CourseContainer, self).__setitem__(name, course)

    def addCourse(self, course):
        """See corresponding docstring in certificatecontainer.py.
        """
        self[getattr(course, 'code', None)] = course

    def clear(self):
        """See corresponding docstring and comments in certificatecontainer.py.
        """
        self._SampleContainer__data.clear()
        del self.__dict__['_BTreeContainer__len']

class CourseContainerFactory(grok.GlobalUtility):
    """A factory for course containers.
    """
    grok.implements(IFactory)
    grok.name(u'waeup.CourseContainer')
    title = u"Create a new course container.",
    description = u"This factory instantiates new course containers."

    def __call__(self, *args, **kw):
        return CourseContainer(*args, **kw)

    def getInterfaces(self):
        return implementedBy(CourseContainer)
