# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
"""
Wrappers for piston Emitter classes.

When outputting a queryset of selected models, instead of returning
XML or JSON stanzas, SSI include statements are returned.

"""
from django.core.urlresolvers import reverse
from django.db.models.query import QuerySet
from piston.emitters import Emitter, XMLEmitter, JSONEmitter
from catalogue.models import Book, Fragment, Tag
from django.utils.translation import get_language


class SsiQS(object):
    """A wrapper for QuerySet that won't serialize."""

    def __init__(self, queryset):
        self.queryset = queryset

    def __unicode__(self):
        raise TypeError("This is not serializable.")

    def get_ssis(self, emitter_format):
        """Yields SSI include statements for the queryset."""
        url_pattern = reverse(
            'api_include',
            kwargs={
                'model': self.queryset.model.__name__.lower(),
                'pk': '0000',
                'emitter_format': emitter_format,
                'lang': get_language(),
            })
        for instance in self.queryset:
            yield "<!--#include file='%s'-->" % url_pattern.replace('0000', str(instance.pk))


class SsiEmitterMixin(object):
    def construct(self):
        if isinstance(self.data, QuerySet) and self.data.model in (Book, Fragment, Tag):
            return SsiQS(self.data)
        else:
            return super(SsiEmitterMixin, self).construct()  # WTF


class SsiJsonEmitter(SsiEmitterMixin, JSONEmitter):
    def render(self, request):
        try:
            return super(SsiJsonEmitter, self).render(request)
        except TypeError:
            return '[%s]' % ",".join(self.construct().get_ssis('json'))

Emitter.register('json', SsiJsonEmitter, 'application/json; charset=utf-8')


class SsiXmlEmitter(SsiEmitterMixin, XMLEmitter):
    def render(self, request):
        try:
            return super(SsiXmlEmitter, self).render(request)
        except TypeError:
            return '<?xml version="1.0" encoding="utf-8"?>\n' \
                '<response><resource>%s</resource></response>' % \
                '</resource><resource>'.join(self.construct().get_ssis('xml'))

Emitter.register('xml', SsiXmlEmitter, 'text/xml; charset=utf-8')
