# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""A library for converting service configs to discovery docs."""

from __future__ import absolute_import

import collections
import json
import logging
import re

from . import api_exceptions
from . import message_parser
from . import message_types
from . import messages
from . import remote
from . import resource_container
from . import util

_logger = logging.getLogger(__name__)
_PATH_VARIABLE_PATTERN = r'{([a-zA-Z_][a-zA-Z_.\d]*)}'

_MULTICLASS_MISMATCH_ERROR_TEMPLATE = (
    'Attempting to implement service %s, version %s, with multiple '
    'classes that are not compatible. See docstring for api() for '
    'examples how to implement a multi-class API.')

_INVALID_AUTH_ISSUER = 'No auth issuer named %s defined in this Endpoints API.'

_API_KEY = 'api_key'
_API_KEY_PARAM = 'key'

CUSTOM_VARIANT_MAP = {
    messages.Variant.DOUBLE: ('number', 'double'),
    messages.Variant.FLOAT: ('number', 'float'),
    messages.Variant.INT64: ('string', 'int64'),
    messages.Variant.SINT64: ('string', 'int64'),
    messages.Variant.UINT64: ('string', 'uint64'),
    messages.Variant.INT32: ('integer', 'int32'),
    messages.Variant.SINT32: ('integer', 'int32'),
    messages.Variant.UINT32: ('integer', 'uint32'),
    messages.Variant.BOOL: ('boolean', None),
    messages.Variant.STRING: ('string', None),
    messages.Variant.BYTES: ('string', 'byte'),
    messages.Variant.ENUM: ('string', None),
}



class DiscoveryGenerator(object):
  """Generates a discovery doc from a ProtoRPC service.

  Example:

    class HelloRequest(messages.Message):
      my_name = messages.StringField(1, required=True)

    class HelloResponse(messages.Message):
      hello = messages.StringField(1, required=True)

    class HelloService(remote.Service):

      @remote.method(HelloRequest, HelloResponse)
      def hello(self, request):
        return HelloResponse(hello='Hello there, %s!' %
                             request.my_name)

    api_config = DiscoveryGenerator().pretty_print_config_to_json(HelloService)

  The resulting api_config will be a JSON discovery document describing the API
  implemented by HelloService.
  """

  # Constants for categorizing a request method.
  # __NO_BODY - Request without a request body, such as GET and DELETE methods.
  # __HAS_BODY - Request (such as POST/PUT/PATCH) with info in the request body.
  __NO_BODY = 1  # pylint: disable=invalid-name
  __HAS_BODY = 2  # pylint: disable=invalid-name

  def __init__(self, request=None):
    self.__parser = message_parser.MessageTypeToJsonSchema()

    # Maps method id to the request schema id.
    self.__request_schema = {}

    # Maps method id to the response schema id.
    self.__response_schema = {}

    # The ApiRequest that called this generator
    self.__request = request

  def _get_resource_path(self, method_id):
    """Return the resource path for a method or an empty array if none."""
    return method_id.split('.')[1:-1]

  def _get_canonical_method_id(self, method_id):
    return method_id.split('.')[-1]

  def __get_request_kind(self, method_info):
    """Categorize the type of the request.

    Args:
      method_info: _MethodInfo, method information.

    Returns:
      The kind of request.
    """
    if method_info.http_method in ('GET', 'DELETE'):
      return self.__NO_BODY
    else:
      return self.__HAS_BODY

  def __field_to_subfields(self, field, cycle=tuple()):
    """Fully describes data represented by field, including the nested case.

    In the case that the field is not a message field, we have no fields nested
    within a message definition, so we can simply return that field. However, in
    the nested case, we can't simply describe the data with one field or even
    with one chain of fields.

    For example, if we have a message field

      m_field = messages.MessageField(RefClass, 1)

    which references a class with two fields:

      class RefClass(messages.Message):
        one = messages.StringField(1)
        two = messages.IntegerField(2)

    then we would need to include both one and two to represent all the
    data contained.

    Calling __field_to_subfields(m_field) would return:
    [
      [<MessageField "m_field">, <StringField "one">],
      [<MessageField "m_field">, <StringField "two">],
    ]

    If the second field was instead a message field

      class RefClass(messages.Message):
        one = messages.StringField(1)
        two = messages.MessageField(OtherRefClass, 2)

    referencing another class with two fields

      class OtherRefClass(messages.Message):
        three = messages.BooleanField(1)
        four = messages.FloatField(2)

    then we would need to recurse one level deeper for two.

    With this change, calling __field_to_subfields(m_field) would return:
    [
      [<MessageField "m_field">, <StringField "one">],
      [<MessageField "m_field">, <StringField "two">, <StringField "three">],
      [<MessageField "m_field">, <StringField "two">, <StringField "four">],
    ]

    Args:
      field: An instance of a subclass of messages.Field.

    Returns:
      A list of lists, where each sublist is a list of fields.
    """
    # Termination condition
    if not isinstance(field, messages.MessageField):
      return [[field]]

    if field.message_type.__name__ in cycle:
      # We have a recursive cycle of messages. Call it quits.
      return []

    result = []
    for subfield in sorted(field.message_type.all_fields(),
                           key=lambda f: f.number):
      cycle = cycle + (field.message_type.__name__, )
      subfield_results = self.__field_to_subfields(subfield, cycle=cycle)
      for subfields_list in subfield_results:
        subfields_list.insert(0, field)
        result.append(subfields_list)
    return result

  def __field_to_parameter_type_and_format(self, field):
    """Converts the field variant type into a tuple describing the parameter.

    Args:
      field: An instance of a subclass of messages.Field.

    Returns:
      A tuple with the type and format of the field, respectively.

    Raises:
      TypeError: if the field variant is a message variant.
    """
    # We use lowercase values for types (e.g. 'string' instead of 'STRING').
    variant = field.variant
    if variant == messages.Variant.MESSAGE:
      raise TypeError('A message variant cannot be used in a parameter.')

    # Note that the 64-bit integers are marked as strings -- this is to
    # accommodate JavaScript, which would otherwise demote them to 32-bit
    # integers.

    return CUSTOM_VARIANT_MAP.get(variant) or (variant.name.lower(), None)

  def __get_path_parameters(self, path):
    """Parses path paremeters from a URI path and organizes them by parameter.

    Some of the parameters may correspond to message fields, and so will be
    represented as segments corresponding to each subfield; e.g. first.second if
    the field "second" in the message field "first" is pulled from the path.

    The resulting dictionary uses the first segments as keys and each key has as
    value the list of full parameter values with first segment equal to the key.

    If the match path parameter is null, that part of the path template is
    ignored; this occurs if '{}' is used in a template.

    Args:
      path: String; a URI path, potentially with some parameters.

    Returns:
      A dictionary with strings as keys and list of strings as values.
    """
    path_parameters_by_segment = {}
    for format_var_name in re.findall(_PATH_VARIABLE_PATTERN, path):
      first_segment = format_var_name.split('.', 1)[0]
      matches = path_parameters_by_segment.setdefault(first_segment, [])
      matches.append(format_var_name)

    return path_parameters_by_segment

  def __validate_simple_subfield(self, parameter, field, segment_list,
                                 segment_index=0):
    """Verifies that a proposed subfield actually exists and is a simple field.

    Here, simple means it is not a MessageField (nested).

    Args:
      parameter: String; the '.' delimited name of the current field being
          considered. This is relative to some root.
      field: An instance of a subclass of messages.Field. Corresponds to the
          previous segment in the path (previous relative to _segment_index),
          since this field should be a message field with the current segment
          as a field in the message class.
      segment_list: The full list of segments from the '.' delimited subfield
          being validated.
      segment_index: Integer; used to hold the position of current segment so
          that segment_list can be passed as a reference instead of having to
          copy using segment_list[1:] at each step.

    Raises:
      TypeError: If the final subfield (indicated by _segment_index relative
        to the length of segment_list) is a MessageField.
      TypeError: If at any stage the lookup at a segment fails, e.g if a.b
        exists but a.b.c does not exist. This can happen either if a.b is not
        a message field or if a.b.c is not a property on the message class from
        a.b.
    """
    if segment_index >= len(segment_list):
      # In this case, the field is the final one, so should be simple type
      if isinstance(field, messages.MessageField):
        field_class = field.__class__.__name__
        raise TypeError('Can\'t use messages in path. Subfield %r was '
                        'included but is a %s.' % (parameter, field_class))
      return

    segment = segment_list[segment_index]
    parameter += '.' + segment
    try:
      field = field.type.field_by_name(segment)
    except (AttributeError, KeyError):
      raise TypeError('Subfield %r from path does not exist.' % (parameter,))

    self.__validate_simple_subfield(parameter, field, segment_list,
                                    segment_index=segment_index + 1)

  def __validate_path_parameters(self, field, path_parameters):
    """Verifies that all path parameters correspond to an existing subfield.

    Args:
      field: An instance of a subclass of messages.Field. Should be the root
          level property name in each path parameter in path_parameters. For
          example, if the field is called 'foo', then each path parameter should
          begin with 'foo.'.
      path_parameters: A list of Strings representing URI parameter variables.

    Raises:
      TypeError: If one of the path parameters does not start with field.name.
    """
    for param in path_parameters:
      segment_list = param.split('.')
      if segment_list[0] != field.name:
        raise TypeError('Subfield %r can\'t come from field %r.'
                        % (param, field.name))
      self.__validate_simple_subfield(field.name, field, segment_list[1:])

  def __parameter_default(self, field):
    """Returns default value of field if it has one.

    Args:
      field: A simple field.

    Returns:
      The default value of the field, if any exists, with the exception of an
          enum field, which will have its value cast to a string.
    """
    if field.default:
      if isinstance(field, messages.EnumField):
        return field.default.name
      elif isinstance(field, messages.BooleanField):
        # The Python standard representation of a boolean value causes problems
        # when generating client code.
        return 'true' if field.default else 'false'
      else:
        return str(field.default)

  def __parameter_enum(self, param):
    """Returns enum descriptor of a parameter if it is an enum.

    An enum descriptor is a list of keys.

    Args:
      param: A simple field.

    Returns:
      The enum descriptor for the field, if it's an enum descriptor, else
          returns None.
    """
    if isinstance(param, messages.EnumField):
      return [enum_entry[0] for enum_entry in sorted(
          param.type.to_dict().items(), key=lambda v: v[1])]

  def __parameter_descriptor(self, param):
    """Creates descriptor for a parameter.

    Args:
      param: The parameter to be described.

    Returns:
      Dictionary containing a descriptor for the parameter.
    """
    descriptor = {}

    param_type, param_format = self.__field_to_parameter_type_and_format(param)

    # Required
    if param.required:
      descriptor['required'] = True

    # Type
    descriptor['type'] = param_type

    # Format (optional)
    if param_format:
      descriptor['format'] = param_format

    # Default
    default = self.__parameter_default(param)
    if default is not None:
      descriptor['default'] = default

    # Repeated
    if param.repeated:
      descriptor['repeated'] = True

    # Enum
    # Note that enumDescriptions are not currently supported using the
    # framework's annotations, so just insert blank strings.
    enum_descriptor = self.__parameter_enum(param)
    if enum_descriptor is not None:
      descriptor['enum'] = enum_descriptor
      descriptor['enumDescriptions'] = [''] * len(enum_descriptor)

    return descriptor

  def __add_parameter(self, param, path_parameters, params):
    """Adds all parameters in a field to a method parameters descriptor.

    Simple fields will only have one parameter, but a message field 'x' that
    corresponds to a message class with fields 'y' and 'z' will result in
    parameters 'x.y' and 'x.z', for example. The mapping from field to
    parameters is mostly handled by __field_to_subfields.

    Args:
      param: Parameter to be added to the descriptor.
      path_parameters: A list of parameters matched from a path for this field.
         For example for the hypothetical 'x' from above if the path was
         '/a/{x.z}/b/{other}' then this list would contain only the element
         'x.z' since 'other' does not match to this field.
      params: List of parameters. Each parameter in the field.
    """
    # If this is a simple field, just build the descriptor and append it.
    # Otherwise, build a schema and assign it to this descriptor
    descriptor = None
    if not isinstance(param, messages.MessageField):
      name = param.name
      descriptor = self.__parameter_descriptor(param)
      descriptor['location'] = 'path' if name in path_parameters else 'query'

      if descriptor:
        params[name] = descriptor
    else:
      for subfield_list in self.__field_to_subfields(param):
        name = '.'.join(subfield.name for subfield in subfield_list)
        descriptor = self.__parameter_descriptor(subfield_list[-1])
        if name in path_parameters:
          descriptor['required'] = True
          descriptor['location'] = 'path'
        else:
          descriptor.pop('required', None)
          descriptor['location'] = 'query'

        if descriptor:
          params[name] = descriptor


  def __params_descriptor_without_container(self, message_type,
                                            request_kind, path):
    """Describe parameters of a method which does not use a ResourceContainer.

    Makes sure that the path parameters are included in the message definition
    and adds any required fields and URL query parameters.

    This method is to preserve backwards compatibility and will be removed in
    a future release.

    Args:
      message_type: messages.Message class, Message with parameters to describe.
      request_kind: The type of request being made.
      path: string, HTTP path to method.

    Returns:
      A list of dicts: Descriptors of the parameters
    """
    params = {}

    path_parameter_dict = self.__get_path_parameters(path)
    for field in sorted(message_type.all_fields(), key=lambda f: f.number):
      matched_path_parameters = path_parameter_dict.get(field.name, [])
      self.__validate_path_parameters(field, matched_path_parameters)
      if matched_path_parameters or request_kind == self.__NO_BODY:
        self.__add_parameter(field, matched_path_parameters, params)

    return params

  def __params_descriptor(self, message_type, request_kind, path, method_id,
                          request_params_class):
    """Describe the parameters of a method.

    If the message_type is not a ResourceContainer, will fall back to
    __params_descriptor_without_container (which will eventually be deprecated).

    If the message type is a ResourceContainer, then all path/query parameters
    will come from the ResourceContainer. This method will also make sure all
    path parameters are covered by the message fields.

    Args:
      message_type: messages.Message or ResourceContainer class, Message with
        parameters to describe.
      request_kind: The type of request being made.
      path: string, HTTP path to method.
      method_id: string, Unique method identifier (e.g. 'myapi.items.method')
      request_params_class: messages.Message, the original params message when
        using a ResourceContainer. Otherwise, this should be null.

    Returns:
      A tuple (dict, list of string): Descriptor of the parameters, Order of the
        parameters.
    """
    path_parameter_dict = self.__get_path_parameters(path)

    if request_params_class is None:
      if path_parameter_dict:
        _logger.warning('Method %s specifies path parameters but you are not '
                        'using a ResourceContainer; instead, you are using %r. '
                        'This will fail in future releases; please switch to '
                        'using ResourceContainer as soon as possible.',
                        method_id, type(message_type))
      return self.__params_descriptor_without_container(
          message_type, request_kind, path)

    # From here, we can assume message_type is from a ResourceContainer.
    message_type = request_params_class

    params = {}

    # Make sure all path parameters are covered.
    for field_name, matched_path_parameters in path_parameter_dict.items():
      field = message_type.field_by_name(field_name)
      self.__validate_path_parameters(field, matched_path_parameters)

    # Add all fields, sort by field.number since we have parameterOrder.
    for field in sorted(message_type.all_fields(), key=lambda f: f.number):
      matched_path_parameters = path_parameter_dict.get(field.name, [])
      self.__add_parameter(field, matched_path_parameters, params)

    return params

  def __params_order_descriptor(self, message_type, path, is_params_class=False):
    """Describe the order of path parameters.

    Args:
      message_type: messages.Message class, Message with parameters to describe.
      path: string, HTTP path to method.
      is_params_class: boolean, Whether the message represents URL parameters.

    Returns:
      Descriptor list for the parameter order.
    """
    path_params = []
    query_params = []
    path_parameter_dict = self.__get_path_parameters(path)

    for field in sorted(message_type.all_fields(), key=lambda f: f.number):
      matched_path_parameters = path_parameter_dict.get(field.name, [])
      if not isinstance(field, messages.MessageField):
        name = field.name
        if name in matched_path_parameters:
          path_params.append(name)
        elif is_params_class and field.required:
          query_params.append(name)
      else:
        for subfield_list in self.__field_to_subfields(field):
          name = '.'.join(subfield.name for subfield in subfield_list)
          if name in matched_path_parameters:
            path_params.append(name)
          elif is_params_class and field.required:
            query_params.append(name)

    return path_params + sorted(query_params)

  def __schemas_descriptor(self):
    """Describes the schemas section of the discovery document.

    Returns:
      Dictionary describing the schemas of the document.
    """
    # Filter out any keys that aren't 'properties', 'type', or 'id'
    result = {}
    for schema_key, schema_value in self.__parser.schemas().items():
      field_keys = schema_value.keys()
      key_result = {}

      # Some special processing for the properties value
      if 'properties' in field_keys:
        key_result['properties'] = schema_value['properties'].copy()
        # Add in enumDescriptions for any enum properties and strip out
        # the required tag for consistency with Java framework
        for prop_key, prop_value in schema_value['properties'].items():
          if 'enum' in prop_value:
            num_enums = len(prop_value['enum'])
            key_result['properties'][prop_key]['enumDescriptions'] = (
                [''] * num_enums)
          elif 'default' in prop_value:
            # stringify default values
            if prop_value.get('type') == 'boolean':
              prop_value['default'] = 'true' if prop_value['default'] else 'false'
            else:
              prop_value['default'] = str(prop_value['default'])
          key_result['properties'][prop_key].pop('required', None)

      for key in ('type', 'id', 'description'):
        if key in field_keys:
          key_result[key] = schema_value[key]

      if key_result:
        result[schema_key] = key_result

    # Add 'type': 'object' to all object properties
    for schema_value in result.values():
      for field_value in schema_value.values():
        if isinstance(field_value, dict):
          if '$ref' in field_value:
            field_value['type'] = 'object'

    return result

  def __request_message_descriptor(self, request_kind, message_type, method_id,
                                   request_body_class):
    """Describes the parameters and body of the request.

    Args:
      request_kind: The type of request being made.
      message_type: messages.Message or ResourceContainer class. The message to
          describe.
      method_id: string, Unique method identifier (e.g. 'myapi.items.method')
      request_body_class: messages.Message of the original body when using
          a ResourceContainer. Otherwise, this should be null.

    Returns:
      Dictionary describing the request.

    Raises:
      ValueError: if the method path and request required fields do not match
    """
    if request_body_class:
      message_type = request_body_class

    if (request_kind != self.__NO_BODY and
        message_type != message_types.VoidMessage()):
      self.__request_schema[method_id] = self.__parser.add_message(
          message_type.__class__)
      return {
          '$ref': self.__request_schema[method_id],
          'parameterName': 'resource',
      }

  def __response_message_descriptor(self, message_type, method_id):
    """Describes the response.

    Args:
      message_type: messages.Message class, The message to describe.
      method_id: string, Unique method identifier (e.g. 'myapi.items.method')

    Returns:
      Dictionary describing the response.
    """
    if message_type != message_types.VoidMessage():
      self.__parser.add_message(message_type.__class__)
      self.__response_schema[method_id] = self.__parser.ref_for_message_type(
          message_type.__class__)
      return {'$ref': self.__response_schema[method_id]}
    else:
      return None

  def __method_descriptor(self, service, method_info,
                          protorpc_method_info):
    """Describes a method.

    Args:
      service: endpoints.Service, Implementation of the API as a service.
      method_info: _MethodInfo, Configuration for the method.
      protorpc_method_info: protorpc.remote._RemoteMethodInfo, ProtoRPC
        description of the method.

    Returns:
      Dictionary describing the method.
    """
    descriptor = {}

    request_message_type = (resource_container.ResourceContainer.
                            get_request_message(protorpc_method_info.remote))
    request_kind = self.__get_request_kind(method_info)
    remote_method = protorpc_method_info.remote

    method_id = method_info.method_id(service.api_info)

    path = method_info.get_path(service.api_info)

    description = protorpc_method_info.remote.method.__doc__

    descriptor['id'] = method_id
    descriptor['path'] = path
    descriptor['httpMethod'] = method_info.http_method

    if description:
      descriptor['description'] = description

    descriptor['scopes'] = [
        'https://www.googleapis.com/auth/userinfo.email'
    ]

    parameters = self.__params_descriptor(
        request_message_type, request_kind, path, method_id,
        method_info.request_params_class)
    if parameters:
      descriptor['parameters'] = parameters

    if method_info.request_params_class:
      parameter_order = self.__params_order_descriptor(
        method_info.request_params_class, path, is_params_class=True)
    else:
      parameter_order = self.__params_order_descriptor(
        request_message_type, path, is_params_class=False)
    if parameter_order:
      descriptor['parameterOrder'] = parameter_order

    request_descriptor = self.__request_message_descriptor(
        request_kind, request_message_type, method_id,
        method_info.request_body_class)
    if request_descriptor is not None:
      descriptor['request'] = request_descriptor

    response_descriptor = self.__response_message_descriptor(
        remote_method.response_type(), method_info.method_id(service.api_info))
    if response_descriptor is not None:
      descriptor['response'] = response_descriptor

    return descriptor

  def __resource_descriptor(self, resource_path, methods):
    """Describes a resource.

    Args:
      resource_path: string, the path of the resource (e.g., 'entries.items')
      methods: list of tuples of type
        (endpoints.Service, protorpc.remote._RemoteMethodInfo), the methods
        that serve this resource.

    Returns:
      Dictionary describing the resource.
    """
    descriptor = {}
    method_map = {}
    sub_resource_index = collections.defaultdict(list)
    sub_resource_map = {}

    resource_path_tokens = resource_path.split('.')
    for service, protorpc_meth_info in methods:
      method_info = getattr(protorpc_meth_info, 'method_info', None)
      path = method_info.get_path(service.api_info)
      method_id = method_info.method_id(service.api_info)
      canonical_method_id = self._get_canonical_method_id(method_id)

      current_resource_path = self._get_resource_path(method_id)

      # Sanity-check that this method belongs to the resource path
      if (current_resource_path[:len(resource_path_tokens)] !=
          resource_path_tokens):
        raise api_exceptions.ToolError(
            'Internal consistency error in resource path {0}'.format(
                current_resource_path))

      # Remove the portion of the current method's resource path that's already
      # part of the resource path at this level.
      effective_resource_path = current_resource_path[
          len(resource_path_tokens):]

      # If this method is part of a sub-resource, note it and skip it for now
      if effective_resource_path:
        sub_resource_name = effective_resource_path[0]
        new_resource_path = '.'.join([resource_path, sub_resource_name])
        sub_resource_index[new_resource_path].append(
            (service, protorpc_meth_info))
      else:
        method_map[canonical_method_id] = self.__method_descriptor(
            service, method_info, protorpc_meth_info)

    # Process any sub-resources
    for sub_resource, sub_resource_methods in sub_resource_index.items():
      sub_resource_name = sub_resource.split('.')[-1]
      sub_resource_map[sub_resource_name] = self.__resource_descriptor(
          sub_resource, sub_resource_methods)

    if method_map:
      descriptor['methods'] = method_map

    if sub_resource_map:
      descriptor['resources'] = sub_resource_map

    return descriptor

  def __standard_parameters_descriptor(self):
    return {
        'alt': {
            'type': 'string',
            'description': 'Data format for the response.',
            'default': 'json',
            'enum': ['json'],
            'enumDescriptions': [
                'Responses with Content-Type of application/json'
            ],
            'location': 'query',
        },
        'fields': {
          'type': 'string',
          'description': 'Selector specifying which fields to include in a '
                         'partial response.',
          'location': 'query',
        },
        'key': {
            'type': 'string',
            'description': 'API key. Your API key identifies your project and '
                           'provides you with API access, quota, and reports. '
                           'Required unless you provide an OAuth 2.0 token.',
            'location': 'query',
        },
        'oauth_token': {
            'type': 'string',
            'description': 'OAuth 2.0 token for the current user.',
            'location': 'query',
        },
        'prettyPrint': {
            'type': 'boolean',
            'description': 'Returns response with indentations and line '
                           'breaks.',
            'default': 'true',
            'location': 'query',
        },
        'quotaUser': {
            'type': 'string',
            'description': 'Available to use for quota purposes for '
                           'server-side applications. Can be any arbitrary '
                           'string assigned to a user, but should not exceed '
                           '40 characters. Overrides userIp if both are '
                           'provided.',
            'location': 'query',
        },
        'userIp': {
            'type': 'string',
            'description': 'IP address of the site where the request '
                           'originates. Use this if you want to enforce '
                           'per-user limits.',
            'location': 'query',
        },
    }

  def __standard_auth_descriptor(self, services):
    scopes = {}
    for service in services:
      for scope in service.api_info.scope_objs:
        scopes[scope.scope] = {'description': scope.description}
    return {
        'oauth2': {
            'scopes': scopes
        }
    }

  def __get_merged_api_info(self, services):
    """Builds a description of an API.

    Args:
      services: List of protorpc.remote.Service instances implementing an
        api/version.

    Returns:
      The _ApiInfo object to use for the API that the given services implement.
    """
    base_paths = sorted(set(s.api_info.base_path for s in services))
    if len(base_paths) != 1:
      raise api_exceptions.ApiConfigurationError(
          'Multiple base_paths found: {!r}'.format(base_paths))
    names_versions = sorted(set(
        (s.api_info.name, s.api_info.api_version) for s in services))
    if len(names_versions) != 1:
      raise api_exceptions.ApiConfigurationError(
          'Multiple apis/versions found: {!r}'.format(names_versions))
    return services[0].api_info

  def __discovery_doc_descriptor(self, services, hostname=None):
    """Builds a discovery doc for an API.

    Args:
      services: List of protorpc.remote.Service instances implementing an
        api/version.
      hostname: string, Hostname of the API, to override the value set on the
        current service. Defaults to None.

    Returns:
      A dictionary that can be deserialized into JSON in discovery doc format.

    Raises:
      ApiConfigurationError: If there's something wrong with the API
        configuration, such as a multiclass API decorated with different API
        descriptors (see the docstring for api()), or a repeated method
        signature.
    """
    merged_api_info = self.__get_merged_api_info(services)
    descriptor = self.get_descriptor_defaults(merged_api_info,
                                              hostname=hostname)

    description = merged_api_info.description
    if not description and len(services) == 1:
      description = services[0].__doc__
    if description:
      descriptor['description'] = description

    descriptor['parameters'] = self.__standard_parameters_descriptor()
    descriptor['auth'] = self.__standard_auth_descriptor(services)

    # Add namespace information, if provided
    if merged_api_info.namespace:
      descriptor['ownerDomain'] = merged_api_info.namespace.owner_domain
      descriptor['ownerName'] = merged_api_info.namespace.owner_name
      descriptor['packagePath'] = merged_api_info.namespace.package_path or ''
    else:
      if merged_api_info.owner_domain is not None:
        descriptor['ownerDomain'] = merged_api_info.owner_domain
      if merged_api_info.owner_name is not None:
        descriptor['ownerName'] = merged_api_info.owner_name
      if merged_api_info.package_path is not None:
        descriptor['packagePath'] = merged_api_info.package_path

    method_map = {}
    method_collision_tracker = {}
    rest_collision_tracker = {}

    resource_index = collections.defaultdict(list)
    resource_map = {}

    # For the first pass, only process top-level methods (that is, those methods
    # that are unattached to a resource).
    for service in services:
      remote_methods = service.all_remote_methods()

      for protorpc_meth_name, protorpc_meth_info in remote_methods.items():
        method_info = getattr(protorpc_meth_info, 'method_info', None)
        # Skip methods that are not decorated with @method
        if method_info is None:
          continue
        path = method_info.get_path(service.api_info)
        method_id = method_info.method_id(service.api_info)
        canonical_method_id = self._get_canonical_method_id(method_id)
        resource_path = self._get_resource_path(method_id)

        # Make sure the same method name isn't repeated.
        if method_id in method_collision_tracker:
          raise api_exceptions.ApiConfigurationError(
              'Method %s used multiple times, in classes %s and %s' %
              (method_id, method_collision_tracker[method_id],
               service.__name__))
        else:
          method_collision_tracker[method_id] = service.__name__

        # Make sure the same HTTP method & path aren't repeated.
        rest_identifier = (method_info.http_method, path)
        if rest_identifier in rest_collision_tracker:
          raise api_exceptions.ApiConfigurationError(
              '%s path "%s" used multiple times, in classes %s and %s' %
              (method_info.http_method, path,
               rest_collision_tracker[rest_identifier],
               service.__name__))
        else:
          rest_collision_tracker[rest_identifier] = service.__name__

        # If this method is part of a resource, note it and skip it for now
        if resource_path:
          resource_index[resource_path[0]].append((service, protorpc_meth_info))
        else:
          method_map[canonical_method_id] = self.__method_descriptor(
              service, method_info, protorpc_meth_info)

    # Do another pass for methods attached to resources
    for resource, resource_methods in resource_index.items():
      resource_map[resource] = self.__resource_descriptor(resource,
          resource_methods)

    if method_map:
      descriptor['methods'] = method_map

    if resource_map:
      descriptor['resources'] = resource_map

    # Add schemas, if any
    schemas = self.__schemas_descriptor()
    if schemas:
      descriptor['schemas'] = schemas

    return descriptor

  def get_descriptor_defaults(self, api_info, hostname=None):
    """Gets a default configuration for a service.

    Args:
      api_info: _ApiInfo object for this service.
      hostname: string, Hostname of the API, to override the value set on the
        current service. Defaults to None.

    Returns:
      A dictionary with the default configuration.
    """
    if self.__request:
      hostname = self.__request.reconstruct_hostname()
      protocol = self.__request.url_scheme
    else:
      hostname = (hostname or util.get_app_hostname() or
                  api_info.hostname)
      protocol = 'http' if ((hostname and hostname.startswith('localhost')) or
                            util.is_running_on_devserver()) else 'https'
    full_base_path = '{0}{1}/{2}/'.format(api_info.base_path,
                                          api_info.name,
                                          api_info.path_version)
    base_url = '{0}://{1}{2}'.format(protocol, hostname, full_base_path)
    root_url = '{0}://{1}{2}'.format(protocol, hostname, api_info.base_path)
    defaults = {
        'kind': 'discovery#restDescription',
        'discoveryVersion': 'v1',
        'id': '{0}:{1}'.format(api_info.name, api_info.path_version),
        'name': api_info.name,
        'version': api_info.api_version,
        'icons': {
            'x16': 'https://www.gstatic.com/images/branding/product/1x/googleg_16dp.png',
            'x32': 'https://www.gstatic.com/images/branding/product/1x/googleg_32dp.png'
        },
        'protocol': 'rest',
        'servicePath': '{0}/{1}/'.format(api_info.name, api_info.path_version),
        'batchPath': 'batch',
        'basePath': full_base_path,
        'rootUrl': root_url,
        'baseUrl': base_url,
        'description': 'This is an API',
    }
    if api_info.description:
        defaults['description'] = api_info.description
    if api_info.title:
        defaults['title'] = api_info.title
    if api_info.documentation:
        defaults['documentationLink'] = api_info.documentation
    if api_info.canonical_name:
        defaults['canonicalName'] = api_info.canonical_name

    return defaults

  def get_discovery_doc(self, services, hostname=None):
    """JSON dict description of a protorpc.remote.Service in discovery format.

    Args:
      services: Either a single protorpc.remote.Service or a list of them
        that implements an api/version.
      hostname: string, Hostname of the API, to override the value set on the
        current service. Defaults to None.

    Returns:
      dict, The discovery document as a JSON dict.
    """

    if not isinstance(services, (tuple, list)):
      services = [services]

    # The type of a class that inherits from remote.Service is actually
    # remote._ServiceClass, thanks to metaclass strangeness.
    # pylint: disable=protected-access
    util.check_list_type(services, remote._ServiceClass, 'services',
                         allow_none=False)

    return self.__discovery_doc_descriptor(services, hostname=hostname)

  def pretty_print_config_to_json(self, services, hostname=None):
    """JSON string description of a protorpc.remote.Service in a discovery doc.

    Args:
      services: Either a single protorpc.remote.Service or a list of them
        that implements an api/version.
      hostname: string, Hostname of the API, to override the value set on the
        current service. Defaults to None.

    Returns:
      string, The discovery doc descriptor document as a JSON string.
    """
    descriptor = self.get_discovery_doc(services, hostname)
    return json.dumps(descriptor, sort_keys=True, indent=2,
                      separators=(',', ': '))
