from datetime import datetime, timedelta

from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
from django.template import loader, Template, TemplateDoesNotExist
from django.contrib.sites.models import Site, RequestSite
from django.utils import feedgenerator
from django.utils.tzinfo import FixedOffset
from django.utils.encoding import smart_unicode, iri_to_uri
from django.conf import settings         
from django.template import RequestContext

def add_domain(domain, url):
    if not (url.startswith('http://') or url.startswith('https://')):
        # 'url' must already be ASCII and URL-quoted, so no need for encoding
        # conversions here.
        url = iri_to_uri(u'http://%s%s' % (domain, url))
    return url

class FeedDoesNotExist(ObjectDoesNotExist):
    pass

class Feed(object):
    item_pubdate = None
    item_enclosure_url = None
    feed_type = feedgenerator.DefaultFeed
    title_template = None
    description_template = None

    def __init__(self, slug, request):
        self.slug = slug
        self.request = request
        self.feed_url = request.path
        self.title_template_name = self.title_template or ('feeds/%s_title.html' % slug)
        self.description_template_name = self.description_template or ('feeds/%s_description.html' % slug)

    def item_link(self, item):
        try:
            return item.get_absolute_url()
        except AttributeError:
            raise ImproperlyConfigured, "Give your %s class a get_absolute_url() method, or define an item_link() method in your Feed class." % item.__class__.__name__

    def __get_dynamic_attr(self, attname, obj, default=None):
        try:
            attr = getattr(self, attname)
        except AttributeError:
            return default
        if callable(attr):
            # Check func_code.co_argcount rather than try/excepting the
            # function and catching the TypeError, because something inside
            # the function may raise the TypeError. This technique is more
            # accurate.
            if hasattr(attr, 'func_code'):
                argcount = attr.func_code.co_argcount
            else:
                argcount = attr.__call__.func_code.co_argcount
            if argcount == 2: # one argument is 'self'
                return attr(obj)
            else:
                return attr()
        return attr

    def feed_extra_kwargs(self, obj):
        """
        Returns an extra keyword arguments dictionary that is used when
        initializing the feed generator.
        """
        return {}

    def item_extra_kwargs(self, item):
        """
        Returns an extra keyword arguments dictionary that is used with
        the `add_item` call of the feed generator.
        """
        return {}

    def get_object(self, bits):
        return None

    def get_feed(self, url=None):
        """
        Returns a feedgenerator.DefaultFeed object, fully populated, for
        this feed. Raises FeedDoesNotExist for invalid parameters.
        """
        if url:
            bits = url.split('/')
        else:
            bits = []

        try:
            obj = self.get_object(bits)
        except ObjectDoesNotExist:
            raise FeedDoesNotExist

        if Site._meta.installed:
            current_site = Site.objects.get_current()
        else:
            current_site = RequestSite(self.request)
        
        link = self.__get_dynamic_attr('link', obj)
        link = add_domain(current_site.domain, link)

        feed = self.feed_type(
            title = self.__get_dynamic_attr('title', obj),
            subtitle = self.__get_dynamic_attr('subtitle', obj),
            link = link,
            description = self.__get_dynamic_attr('description', obj),
            language = settings.LANGUAGE_CODE.decode(),
            feed_url = add_domain(current_site.domain,
                                  self.__get_dynamic_attr('feed_url', obj)),
            author_name = self.__get_dynamic_attr('author_name', obj),
            author_link = self.__get_dynamic_attr('author_link', obj),
            author_email = self.__get_dynamic_attr('author_email', obj),
            categories = self.__get_dynamic_attr('categories', obj),
            feed_copyright = self.__get_dynamic_attr('feed_copyright', obj),
            feed_guid = self.__get_dynamic_attr('feed_guid', obj),
            ttl = self.__get_dynamic_attr('ttl', obj),
            **self.feed_extra_kwargs(obj)
        )

        try:
            title_tmp = loader.get_template(self.title_template_name)
        except TemplateDoesNotExist:
            title_tmp = Template('{{ obj }}')
        try:
            description_tmp = loader.get_template(self.description_template_name)
        except TemplateDoesNotExist:
            description_tmp = Template('{{ obj }}')

        for item in self.__get_dynamic_attr('items', obj):
            link = add_domain(current_site.domain, self.__get_dynamic_attr('item_link', item))
            enc = None
            enc_url = self.__get_dynamic_attr('item_enclosure_url', item)
            if enc_url:
                enc = feedgenerator.Enclosure(
                    url = smart_unicode(enc_url),
                    length = smart_unicode(self.__get_dynamic_attr('item_enclosure_length', item)),
                    mime_type = smart_unicode(self.__get_dynamic_attr('item_enclosure_mime_type', item))
                )
            author_name = self.__get_dynamic_attr('item_author_name', item)
            if author_name is not None:
                author_email = self.__get_dynamic_attr('item_author_email', item)
                author_link = self.__get_dynamic_attr('item_author_link', item)
            else:
                author_email = author_link = None

            pubdate = self.__get_dynamic_attr('item_pubdate', item)
            if pubdate:
                now = datetime.now()
                utcnow = datetime.utcnow()

                # Must always subtract smaller time from larger time here.
                if utcnow > now:
                    sign = -1
                    tzDifference = (utcnow - now)
                else:
                    sign = 1
                    tzDifference = (now - utcnow)

                # Round the timezone offset to the nearest half hour.
                tzOffsetMinutes = sign * ((tzDifference.seconds / 60 + 15) / 30) * 30
                tzOffset = timedelta(minutes=tzOffsetMinutes)
                pubdate = pubdate.replace(tzinfo=FixedOffset(tzOffset))

            feed.add_item(
                title = title_tmp.render(RequestContext(self.request, {'obj': item, 'site': current_site})),
                link = link,
                description = description_tmp.render(RequestContext(self.request, {'obj': item, 'site': current_site})),
                unique_id = self.__get_dynamic_attr('item_guid', item, link),
                enclosure = enc,
                pubdate = pubdate,
                author_name = author_name,
                author_email = author_email,
                author_link = author_link,
                categories = self.__get_dynamic_attr('item_categories', item),
                item_copyright = self.__get_dynamic_attr('item_copyright', item),
                **self.item_extra_kwargs(item)
            )
        return feed
