"""Pagination settings."""
from base64 import b64encode
from urllib import parse as urlparse

from django.conf import settings
from rest_framework.pagination import CursorPagination, PageNumberPagination
from django_elasticsearch_dsl_drf.pagination import PageNumberPagination as ESPagination


class ProjectPageNumberPagination(PageNumberPagination):
    """Customized pagination class."""

    page_size_query_param = 'page_size'


class ProjectCursorPagination(CursorPagination):
    """Customized cursor pagination class."""

    def encode_cursor(self, cursor):
        """
        Given a Cursor instance, return an url with encoded cursor.
        """
        tokens = {}
        if cursor.offset != 0:
            tokens['o'] = str(cursor.offset)
        if cursor.reverse:
            tokens['r'] = '1'
        if cursor.position is not None:
            tokens['p'] = cursor.position

        querystring = urlparse.urlencode(tokens, doseq=True)
        encoded = b64encode(querystring.encode('ascii')).decode('ascii')
        return encoded


class ProjectMobilePagination(ProjectPageNumberPagination):
    """Pagination settings for mobile API."""

    def get_next_link(self):
        """Get next link method."""
        if not self.page.has_next():
            return None
        return self.page.next_page_number()

    def get_previous_link(self):
        """Get previous link method."""
        if not self.page.has_previous():
            return None
        return self.page.previous_page_number()


class ESDocumentPagination(ESPagination):
    """Pagination class for ES results. (includes facets)"""
    page_size_query_param = 'page_size'

    def get_next_link(self):
        """Get next link method."""
        if not self.page.has_next():
            return None
        return self.page.next_page_number()

    def get_previous_link(self):
        """Get previous link method."""
        if not self.page.has_previous():
            return None
        return self.page.previous_page_number()

    def get_facets(self, page=None):
        """Get facets.

        :param page:
        :return:
        """
        if page is None:
            page = self.page

        if hasattr(self, 'facets_computed'):
            ret = {}
            for filter_field, bucket_data in self.facets_computed.items():
                ret.update({filter_field: bucket_data.__dict__['_d_']})
            return ret
        elif hasattr(page, 'facets') and hasattr(page.facets, '_d_'):
            return page.facets._d_


class PortionPagination(ProjectMobilePagination):
    """
    Pagination for app establishments with limit page size equal to 12
    """
    page_size = settings.QUERY_OUTPUT_OBJECTS
