# Copyright The IETF Trust 2007, All Rights Reserved

from django.conf import settings
from django.contrib.syndication.feeds import Feed, FeedDoesNotExist
from django.utils.feedgenerator import Atom1Feed
from django.db.models import Q
from ietf.liaisons.models import LiaisonDetail, FromBodies
from ietf.idtracker.models import Acronym
from datetime import datetime, time
import re

if settings.USE_DB_REDESIGN_PROXY_CLASSES:
    from ietf.group.models import Group
    from ietf.liaisons.proxy import LiaisonDetailProxy as LiaisonDetail
    from ietf.liaisons.models import LiaisonStatement

# A slightly funny feed class, the 'object' is really
# just a dict with some parameters that items() uses
# to construct a queryset.
class Liaisons(Feed):
    feed_type = Atom1Feed
    def get_object(self, bits):
	obj = {}
	if bits[0] == 'recent':
	    if len(bits) != 1:
		raise FeedDoesNotExist
	    obj['title'] = 'Recent Liaison Statements'
	    obj['limit'] = 15
	    return obj
	if bits[0] == 'from':
	    if len(bits) != 2:
		raise FeedDoesNotExist
            if settings.USE_DB_REDESIGN_PROXY_CLASSES:
                try:
                    group = Group.objects.get(acronym=bits[1])
                    obj['filter'] = { 'from_group': group }
                    obj['title'] = u'Liaison Statements from %s' % group.name
                    return obj
                except Group.DoesNotExist:
                    # turn all-nonword characters into one-character
                    # wildcards to make it easier to construct the URL
                    search_string = re.sub(r"[^a-zA-Z1-9]", ".", bits[1])
                    statements = LiaisonStatement.objects.filter(from_name__iregex=search_string)
                    if statements:
                        name = statements[0].from_name
                        obj['filter'] = { 'from_name': name }
                        obj['title'] = u'Liaison Statements from %s' % name
                        return obj
                    else:
                        raise FeedDoesNotExist
	    try:
		acronym = Acronym.objects.get(acronym=bits[1])
		obj['filter'] = {'from_id': acronym.acronym_id}
		body = bits[1]
	    except Acronym.DoesNotExist:
		# Find body matches.  Turn all non-word characters
		# into wildcards for the like search.
		# Note that supplying sql here means that this is
		# mysql-specific (e.g., postgresql wants 'ilike' for
		# the same operation)
		body_list = FromBodies.objects.values('from_id','body_name').extra(where=['body_name like "%s"' % re.sub('\W', '_', bits[1])])
		if not body_list:
		    raise FeedDoesNotExist
		frmlist = [b['from_id'] for b in body_list]
		# Assume that all of the matches have the same name.
		# This is not guaranteed (e.g., a url like '-----------'
		# will match several bodies) but is true of well-formed
		# inputs.
		body = body_list[0]['body_name']
		obj['filter'] = {'from_id__in': frmlist}
	    obj['title'] = 'Liaison Statements from %s' % body
	    return obj
	if bits[0] == 'to':
	    if len(bits) != 2:
		raise FeedDoesNotExist
            if settings.USE_DB_REDESIGN_PROXY_CLASSES:
                obj['filter'] = dict(to_name__icontains=bits[1])
            else:
                # The schema uses two different fields for the same
                # basic purpose, depending on whether it's a Secretariat-submitted
                # or Liaison-tool-submitted document.
                obj['q'] = [ (Q(by_secretariat=0) & Q(to_body__icontains=bits[1])) | (Q(by_secretariat=1) & Q(submitter_name__icontains=bits[1])) ]
	    obj['title'] = 'Liaison Statements where to matches %s' % bits[1]
	    return obj
	if bits[0] == 'subject':
	    if len(bits) != 2:
		raise FeedDoesNotExist
            if settings.USE_DB_REDESIGN_PROXY_CLASSES:
                obj['q'] = [ Q(title__icontains=bits[1]) | Q(attachments__title__icontains=bits[1]) ]
            else:
                obj['q'] = [ Q(title__icontains=bits[1]) | Q(uploads__file_title__icontains=bits[1]) ]
	    obj['title'] = 'Liaison Statements where subject matches %s' % bits[1]
	    return obj
	raise FeedDoesNotExist

    def get_feed(self, url=None):
        if not url:
            raise FeedDoesNotExist
        else:
            return Feed.get_feed(self, url=url)

    def title(self, obj):
	return obj['title']

    def link(self, obj):
	# no real equivalent for any objects
	return '/liaison/'

    def description(self, obj):
	return self.title(obj)

    def items(self, obj):
	# Start with the common queryset
	qs = LiaisonDetail.objects.all().order_by("-submitted_date")
	if obj.has_key('q'):
	    qs = qs.filter(*obj['q'])
	if obj.has_key('filter'):
	    qs = qs.filter(**obj['filter'])
	if obj.has_key('limit'):
	    qs = qs[:obj['limit']]
	return qs

    def item_pubdate(self, item):
        # this method needs to return a datetime instance, even
        # though the database has only date, not time 
	return datetime.combine(item.submitted_date, time(0,0,0))
 
    def item_author_name(self, item):
	return item.from_body()
