"""This module holds the class pdf report of the ``pdf_reporting`` app."""

import io

from django.conf import settings
from django.template import Context, loader
from rlextra.rml2pdf import rml2pdf

from mtp.apps.themes.models import Theme


class PDFReport:
    """A PDF Report.

    Notes
    -----
    We use the ReportLab Plus module to create the pdf report.
    https://www.reportlab.com/reportlabplus/

    Without license, we are in evaluation mode.
    To switch in production mode, we must add the directory path which contains the license file
    in the ``PYTHONPATH``.

    Attributes
    ----------
    template_name: str
        The template name used to generate this pdf file.
    context_data: dict
        The context data used to render template.

    """

    content_type = 'application/pdf'

    def __init__(self, template_name, context_data=None):
        self.template_name = template_name
        self.context_data = context_data or {}

    def _get_pdf_context_data(self, **kwargs):
        """Get the pdf context data.

        Notes
        -----
        We add the default theme in the context data.

        """

        kwargs.setdefault('theme', Theme.objects.get_default())
        kwargs.setdefault('settings', settings)
        kwargs.update(self.context_data)
        return kwargs

    def _get_rml_content(self):
        """Get the rendered content of provided rml template.

        Notes
        -----
        Use the `template_name` attribute to select rml template.

        Returns
        -------
        str
            The rendered content of provided rml template.

        """

        rml_template = loader.get_template(self.template_name)
        context_data = Context(self._get_pdf_context_data())
        return rml_template.render(context_data)

    def _generate_pdf(self, output_file):
        """Generate the pdf and save it in `output_file`.

        Parameters
        ----------
        output_file: object
            The output file. Can be io buffer or file path.

        """

        rml2pdf.go(self._get_rml_content(), outputFileName=output_file)

    def get_file_content(self):
        """Get file content.

        Returns
        -------
        bytes
            The pdf file content.

        """

        buffer = io.BytesIO()
        self._generate_pdf(buffer)
        return buffer.getvalue()

    def generate_file(self, file_path):
        """Generate a file with pdf content.

        Parameters
        ----------
        file_path: str
            The file path.

        """

        self._generate_pdf(file_path)


class ObjectPDFReport(PDFReport):
    """A PDF Report from a model object.

    Notes
    -----
    This class must be used when we want create a custom PDFReport from an object.
    Just override the `_get_pdf_context_data` method to pass the needed data.

    Attributes
    ----------
    object: object
        The object used to build the pdf report.

    """

    template_name = None

    def __init__(self, obj, context_data=None):
        super().__init__(template_name=self.template_name, context_data=context_data)
        self.object = obj
