##
## root.py
## Login : <uli@pu.smp.net>
## Started on  Thu Jan 20 04:17:59 2011 Uli Fouquet
## $Id: root.py 7137 2011-11-19 08:37:08Z henrik $
## 
## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
## 
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
"""
The root for applicants.
"""
import grok
from hurry.query import Eq
from hurry.query.interfaces import IQuery
from zope.component import getUtility
from waeup.sirp.interfaces import IWAeUPSIRPPluggable
from waeup.sirp.applicants.interfaces import IApplicantsRoot
from waeup.sirp.utils.helpers import get_current_principal
from waeup.sirp.utils.logger import Logger

class ApplicantsRoot(grok.Container, Logger):
    """The root of applicants-related components. It contains only
    containers for applicants.
    """
    grok.implements(IApplicantsRoot)

    local_roles = ['waeup.ApplicationsOfficer']

    logger_name = 'waeup.sirp.${sitename}.applicants'
    logger_filename = 'applicants.log'

    def logger_info(self, target, ob_class, comment=None):
        """Get the logger's info method.
        """
        user = get_current_principal()
        user = getattr(user, 'id', 'system')
        self.logger.info('%s - %s - %s - %s' % (
                user, target, ob_class, comment))
        return

class ApplicantsPlugin(grok.GlobalUtility):
    """A WAeUPSIRPPlugin that creates an applicants root in portal.

    This plugin should be called by a typical
    `waeup.sirp.app.Universtiy` instance on creation time. The
    :meth:`update` method normally can also be triggered manually over
    the main site configuration.

    Implements :class:`waeup.sirp.interfaces.IWAeUPSIRPPluggable`
    """
    grok.name('applicants')
    grok.implements(IWAeUPSIRPPluggable)
    log_prefix = 'ApplicantsPlugin'

    def setup(self, site, name, logger):
        """Create a new :class:`ApplicantsRoot` instance in `site`.
        """
        site['applicants'] = ApplicantsRoot()
        logger.info(
            '%s: Installed applicants root.' % (self.log_prefix,)
            )
        return

    def update(self, site, name, logger):
        """Update site wide ``applicants`` root.

        If the site already contains a suitable ``applicants`` root,
        leave it that way. If not create one and delete the old one if
        appropriate.
        """
        app_folder = site.get('applicants', None)
        site_name = getattr(site, '__name__', '<Unnamed Site>')
        if IApplicantsRoot.providedBy(app_folder):
            # Applicants up to date. Return.
            logger.info(
                '%s: Updating site at %s: Nothing to do.' % (
                    self.log_prefix, site_name,)
                )
            return
        elif app_folder is not None:
            # Applicants need update. Remove old instance.
            logger.warn(
                '%s: Outdated applicants folder detected at site %s.'
                'Removing it.' % (self.log_prefix, site_name)
                    )
            del site['applicants']
        # Add new applicants.
        logger.info(
            '%s: Updating site at %s. Installing '
            'applicants.' % (self.log_prefix, site_name,)
            )
        self.setup(site, name, logger)
        return

def get_applicant_data(identifier):
    """Get applicant data associated with `identifier`.

    Returns the applicant object if successful and ``None`` else.

    As `identifier` we expect an access code in format
    like ``PREFIX-XXX-YYYYYYYY`` where ``PREFIX`` is something like
    ``APP`` or ``PUDE``, ``XXX`` the access code series and
    ``YYYYYYYYYY`` the real accesscode number.

    This function requires a fully blown setup as it does catalog
    lookups for finding applicants.
    """
    query = getUtility(IQuery)
    results = list(query.searchResults(
            Eq(('applicants_catalog', 'access_code'), identifier)
            ))
    if len(results) == 0:
        return None
    return results[0]

def application_exists(identifier):
    """Check whether an application for the given identifier already
       exists.

       `identifier` will normally be an access code.
    """
    applicant = get_applicant_data(identifier)
    if applicant is None:
        return False
    return True
