# (c) cavaliba.com - paginator.py

from app_home.configuration import get_configuration
from app_data.schema import Schema
from app_data.data import count_instance

# helper to paginate  UI Instance List


def paginator_for_request(request=None, schema=None, update_session=True, max_size=None):

    if not isinstance(schema, Schema):
        return

    if not request:
        return

    paginator = Paginator()
    paginator.count = count_instance(schema.classname)

    if not max_size:
        # default to data view ; for export, should be provided
        max_size = int(get_configuration("data", "DATA_MAX_SIZE"))

    paginator.max_size = max_size
    default_size = int(get_configuration("data", "DATA_DEFAULT_SIZE"))
    default_page = 1

    # session ?
    session_size = request.session.get(schema.classname + "_size", default_size)
    session_page = request.session.get(schema.classname + "_page", default_page)
    try:
        size = int(request.GET.get("size", session_size))
        page = int(request.GET.get("page", session_page))
    except Exception:
        return None


    if page < 1 or size < 1:
        if update_session:
            request.session[schema.classname + "_size"] = default_size
            request.session[schema.classname + "_page"] = default_page
        return None

    if size > paginator.max_size:
        size = default_size

    if (page - 1) * size > paginator.count:
        page = 1
        size = default_size


    paginator.offset = (page - 1) * size
    paginator.limit = paginator.offset + size

    # session
    if update_session:
        request.session[schema.classname + "_size"] = size
        request.session[schema.classname + "_page"] = page


    paginator.size = size
    paginator.page = page

    # PREV | FIRST || CURRENT or ... || LAST | NEXT

    # last
    page_last = int(paginator.count / size) + 1
    paginator.page_last = page_last

    # prev
    if page > 1:
        paginator.page_prev = page - 1
    else:
        paginator.page_prev = page

    #  first
    if page == 1:
        paginator.page_first = True
    else:
        paginator.page_first = False

    #  current
    if page > 1 and page < page_last:
        paginator.page_current = True
    else:
        paginator.page_current = False


    # last_active
    if page < page_last:
        paginator.page_last_active = False
    else:
        paginator.page_last_active = True

    # next
    if page < page_last:
        paginator.page_next = page + 1
    else:
        paginator.page_next = page

    #  list of valid size_for template
    for i in paginator.default_size_list:
        if i <= paginator.max_size:
            paginator.size_list.append(i)


    return paginator



class Paginator:

    def __init__(self):

        self.default_size_list = [1, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 50000, 100000, 500000]
        self.size_list = []     # truncated default_size_list to max_size

        self.count = 0          # total number of items in class
        self.size = 1           # requested size
        self.max_size = 0

        self.offset = 0         # slice from query [offset:limit]
        self.limit = 1

        self.page_prev = 1
        self.page_first = True               # page = 1
        self.page = 1
        self.page_current = False            # True == not first, not last
        self.page_last = 1
        self.page_last_active = True         # True == page = page_last
        self.page_next = 1
