from .type_validation_functions import anything, int_range


def paginate(required=True, max_size=None, last=anything):
  '''
  This is the 'paginate' interface. It standardizes the way we handle APIs that return lists of data, which allows
  clients to handle paginated APIs uniformly, potentially hiding messy repeated code. This function serves as shorthand
  for building the appropriate input validation format to use with your route definitions. For example, say we are
  defining the following route:

  @service.route('/list-products', None, { 'category_id': int })
  def list_products(profile, data):
    # Returns a list of products ordered by product_id (an int) - we want to be able to use that product_id to pagiante
    ...

  To add the pagination parameters, you can do the following:

  @service.route('/list-products', None, { 'category_id': int, **paginate(last=int) })
  def list_products(profile, data):
    # This injects properties into your input validateion format, resulting in the following:
    # { 'category_id': int, 'pagination': { 'last': int } }
    # It's still up to you to implement the actual pagination logic correctly, this just standardizes the parameters
    ...

  Params:
  - required: whether or not pagination is explicitly required for this route
  - max_size: this allows the client to control the page size (using the 'pagination' / 'size' parameter), but only up
    to the value specified. Omit 'max_size' to control the page size in your route implementation.
  - last: the input validation format for the 'pagination' / 'last' parameter

  Returns the input validation format to be added at the top level of the target route's input validation format
  '''

  key = 'paginate' if required else '[paginate]'
  value = { '[last]': last }
  if max_size:
    value['size'] = int_range('[1, %s]' % max_size)
  return { key: value }
