"""This module holds the views of the ``qrcodes`` app."""

import io
import zipfile

from django.http import HttpResponse
from django.views import generic
from slugify import slugify

from mtp.apps.common.views_utils import ExportFileMixin
from .qrcode import QRCode


# pylint: disable=abstract-method
class QRCodeDownloadMixin(ExportFileMixin):
    """Mixin which provide methods and attributes to download an image containing a QRCode.

    Attributes
    ----------
    qrcode_class: QRCode
        The QRCode class to download.
        We can have a specific QRCode. By default, its QRCode, the base class.

    """

    qrcode_class = QRCode


class ObjectQRCodeDownloadDetailView(QRCodeDownloadMixin, generic.DetailView):
    """View to download QrCode able to launch an activity."""

    def get_filename(self):
        """Get the filename used to name the generated png file."""
        return str(self.get_object())

    def get(self, request, *args, **kwargs):
        """Allow to download QRCode image."""
        super().get(self.request, *args, **kwargs)

        qr_code = self.qrcode_class(self.object).generate()
        response = HttpResponse(content_type=self.qrcode_class.content_type)

        filename = self.get_slugified_filename()
        response['Content-Disposition'] = 'attachment; filename=%s.png' % filename

        qr_code.save(response)
        return response


# pylint: disable=abstract-method
class ObjectQRCodeDownloadListView(QRCodeDownloadMixin, generic.ListView):
    """View to download QrCode able to launch an activity."""

    def create_zip_file(self, obj_list):
        """Create zip file containing a QRCode for each provided object.

        Returns
        -------
        BytesIO
            Zip file buffer.

        """
        zip_buffer = io.BytesIO()
        with zipfile.ZipFile(zip_buffer, mode="w") as zip_file:
            for obj in obj_list:
                qr_code = self.qrcode_class(obj).generate()

                qr_code_buffer = io.BytesIO()
                qr_code.save(qr_code_buffer, 'PNG')

                zip_file.writestr(
                    '%s.png' % slugify(str(obj)),
                    qr_code_buffer.getvalue()
                )

        return zip_buffer

    def get(self, request, *args, **kwargs):
        """Allow to download a zip containing QRCode images."""
        super().get(self.request, *args, **kwargs)

        zip_buffer = self.create_zip_file(self.object_list)
        response = HttpResponse(zip_buffer.getvalue(), content_type="application/x-zip-compressed")

        filename = self.get_slugified_filename()
        response['Content-Disposition'] = 'attachment; filename=%s.zip' % filename

        return response
