import logging


from django import forms
from django.conf import settings


from sphene.community import sphutils

from akismet import Akismet


def check_spam(request, body, author_email = None, author_name = None, author_url = None):
    """
    checks the given body for spam. you might pass in additional information
    like the user's email address. otherwise best guesses are used.

    returns True if comment is recognized as spam, False otherwise.
    """
    Akismet.baseurl = settings.AKISMET_BASEURL
    api = Akismet(settings.AKISMET_API_KEY)
    if request.user.is_authenticated():
        if author_email is None:
            author_email = request.user.email
        if author_name is None:
            author_name = request.user.username
    data = {
        'user_ip': request.META.get('REMOTE_ADDR', '127.0.0.1'),
        'user_agent': request.META.get('HTTP_USER_AGENT', ''),
        'referrer': request.META.get('HTTP_REFERER', ''),
        'comment_type': 'comment',
        'comment_author': author_name,
        'comment_author_email': author_email,
        'comment_author_url': author_url,
        }
    try:
        r = api.comment_check(body, data)
        logger.debug('checked comment for spam - result: %r (from %s <%s>)' % (r, author_name, author_email))
        if r:
            logger.info("We detected spam!! body: {%s} - data: {%s}" % (body, repr(data)))
        return r
    except:
        logger.exception('Error while checking for spam.')
        return False



class SpamCheckedForm(forms.Form):
    """
    checks the field called 'comment' if it is spam. and if it is recognized
    as spam, will show a captcha which has to be solved.
    """

    def __init__(self, *args, **kwargs):
        super(SpamCheckedForm, self).__init__(*args, **kwargs)
        if self.data.get('captcha_0', False):
            self._add_captcha_field()

    def _add_captcha_field(self):
        self.fields['captcha'] = sphutils.CaptchaField( \
            label=u'Captcha',
            widget=sphutils.CaptchaWidget,
            help_text = mark_safe(u'Bitte gib das <strong>Ergebnis</strong> der Rechnung ein.'),
            )


    def clean(self):
        if not 'captcha' in self.fields:
            # We only need to to checking if there was no captcha field
            # in the form already.
            d = self.cleaned_data
            body = self.cleaned_data['comment']
            if check_spam(get_current_request(),
                          body,
                          author_email = d.get('email', None),
                          author_name = d.get('name', None),
                          author_url = d.get('url', None)):
                # We got spam :(
                self.cleaned_data['requires_captcha'] = 1
                self._add_captcha_field()
                self._errors['captcha'] = self.error_class([u'Deine Nachricht wurde als Spam erkannt. Bitte löse das Captcha.'])
        return self.cleaned_data

