# 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 OpenAPI (Swagger) specs."""
from __future__ import absolute_import

import hashlib
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 aren\'t 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'
_DEFAULT_SECURITY_DEFINITION = 'google_id_token'


_VALID_API_NAME = re.compile('^[a-z][a-z0-9]{0,39}$')


def _validate_api_name(name):
  valid = (_VALID_API_NAME.match(name) is not None)
  if not valid:
    raise api_exceptions.InvalidApiNameException(
        'The API name must match the regular expression {}'.format(
            _VALID_API_NAME.pattern[1:-1]))
  return name


class OpenApiGenerator(object):
  """Generates an OpenAPI spec 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 = OpenApiGenerator().pretty_print_config_to_json(HelloService)

  The resulting api_config will be a JSON OpenAPI 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):
    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 = {}

  def _add_def_paths(self, prop_dict):
    """Recursive method to add relative paths for any $ref objects.

    Args:
      prop_dict: The property dict to alter.

    Side Effects:
      Alters prop_dict in-place.
    """
    for prop_key, prop_value in prop_dict.items():
      if prop_key == '$ref' and not 'prop_value'.startswith('#'):
        prop_dict[prop_key] = '#/definitions/' + prop_dict[prop_key]
      elif isinstance(prop_value, dict):
        self._add_def_paths(prop_value)

  def _construct_operation_id(self, service_name, protorpc_method_name):
    """Return an operation id for a service method.

    Args:
      service_name: The name of the service.
      protorpc_method_name: The ProtoRPC method name.

    Returns:
      A string representing the operation id.
    """

    # camelCase the ProtoRPC method name
    method_name_camel = util.snake_case_to_headless_camel_case(
        protorpc_method_name)

    return '{0}_{1}'.format(service_name, method_name_camel)

  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):
    """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]]

    result = []
    for subfield in sorted(field.message_type.all_fields(),
                           key=lambda f: f.number):
      subfield_results = self.__field_to_subfields(subfield)
      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 can\'t 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.

    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),
    }
    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
      else:
        return 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 __body_parameter_descriptor(self, method_id):
    return {
        'name': 'body',
        'in': 'body',
        'required': True,
        'schema': {
            '$ref': '#/definitions/{0}'.format(
                self.__request_schema[method_id])
        }
    }

  def __non_body_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 = {}

    descriptor['name'] = param.name

    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
    enum_descriptor = self.__parameter_enum(param)
    if enum_descriptor is not None:
      descriptor['enum'] = enum_descriptor

    return descriptor

  def __path_parameter_descriptor(self, param):
    descriptor = self.__non_body_parameter_descriptor(param)
    descriptor['required'] = True
    descriptor['in'] = 'path'

    return descriptor

  def __query_parameter_descriptor(self, param):
    descriptor = self.__non_body_parameter_descriptor(param)
    descriptor['in'] = 'query'

    # If this is a repeated field, convert it to the collectionFormat: multi
    # style.
    if param.repeated:
      descriptor['collectionFormat'] = 'multi'
      descriptor['items'] = {
        'type': descriptor['type']
      }
      descriptor['type'] = 'array'
      descriptor.pop('repeated', None)

    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
    if not isinstance(param, messages.MessageField):
      if param.name in path_parameters:
        descriptor = self.__path_parameter_descriptor(param)
      else:
        descriptor = self.__query_parameter_descriptor(param)

      params.append(descriptor)
    else:
      # If a subfield of a MessageField is found in the path, build a descriptor
      # for the path parameter.
      for subfield_list in self.__field_to_subfields(param):
        qualified_name = '.'.join(subfield.name for subfield in subfield_list)
        if qualified_name in path_parameters:
          descriptor = self.__path_parameter_descriptor(subfield_list[-1])
          descriptor['required'] = True

          params.append(descriptor)

  def __params_descriptor_without_container(self, message_type,
                                            request_kind, method_id, 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.
      method_id: string, Unique method identifier (e.g. 'myapi.items.method')
      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)

    # If the request has a body, add the body parameter
    if (message_type != message_types.VoidMessage() and
        request_kind == self.__HAS_BODY):
      params.append(self.__body_parameter_descriptor(method_id))

    return params

  def __params_descriptor(self, message_type, request_kind, path, method_id):
    """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')

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

    if not isinstance(message_type, resource_container.ResourceContainer):
      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, method_id, path)

    # From here, we can assume message_type is a ResourceContainer.
    params = []

    # Process body parameter, if any
    if message_type.body_message_class != message_types.VoidMessage:
      params.append(self.__body_parameter_descriptor(method_id))

    # Process path/querystring parameters
    params_message_type = message_type.parameters_message_class()

    # Make sure all path parameters are covered.
    for field_name, matched_path_parameters in path_parameter_dict.items():
      field = params_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(params_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 __request_message_descriptor(self, request_kind, message_type, method_id,
                                   path):
    """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')
      path: string, HTTP path to method.

    Returns:
      Dictionary describing the request.

    Raises:
      ValueError: if the method path and request required fields do not match
    """
    if isinstance(message_type, resource_container.ResourceContainer):
      base_message_type = message_type.body_message_class()
      if (request_kind == self.__NO_BODY and
          base_message_type != message_types.VoidMessage()):
        msg = ('Method %s specifies a body message in its ResourceContainer, but '
               'is a HTTP method type that cannot accept a body.') % method_id
        raise api_exceptions.ApiConfigurationError(msg)
    else:
      base_message_type = message_type

    if (request_kind != self.__NO_BODY and
        base_message_type != message_types.VoidMessage()):
      self.__request_schema[method_id] = self.__parser.add_message(
          base_message_type.__class__)

    params = self.__params_descriptor(message_type, request_kind, path,
                                      method_id)

    return params

  def __definitions_descriptor(self):
    """Describes the definitions section of the OpenAPI spec.

    Returns:
      Dictionary describing the definitions of the spec.
    """
    # Filter out any keys that aren't 'properties' or 'type'
    result = {}
    for def_key, def_value in self.__parser.schemas().items():
      if 'properties' in def_value or 'type' in def_value:
        key_result = {}
        required_keys = set()
        if 'type' in def_value:
          key_result['type'] = def_value['type']
        if 'properties' in def_value:
          for prop_key, prop_value in def_value['properties'].items():
            if isinstance(prop_value, dict) and 'required' in prop_value:
              required_keys.add(prop_key)
              del prop_value['required']
          key_result['properties'] = def_value['properties']
        # Add in the required fields, if any
        if required_keys:
          key_result['required'] = sorted(required_keys)
        result[def_key] = key_result

    # Add 'type': 'object' to all object properties
    # Also, recursively add relative path to all $ref values
    for def_value in result.values():
      for prop_value in def_value.values():
        if isinstance(prop_value, dict):
          if '$ref' in prop_value:
            prop_value['type'] = 'object'
          self._add_def_paths(prop_value)

    return result

  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.
    """

    # Skeleton response descriptor, common to all response objects
    descriptor = {'200': {'description': 'A successful 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__)
      descriptor['200']['schema'] = {'$ref': '#/definitions/{0}'.format(
          self.__response_schema[method_id])}

    return dict(descriptor)

  def __x_google_quota_descriptor(self, metric_costs):
    """Describes the metric costs for a call.

    Args:
      metric_costs: Dict of metric definitions to the integer cost value against
        that metric.

    Returns:
      A dict descriptor describing the Quota limits for the endpoint.
    """
    return {
        'metricCosts': {
            metric: cost for (metric, cost) in metric_costs.items()
        }
    } if metric_costs else None

  def __x_google_quota_definitions_descriptor(self, limit_definitions):
    """Describes the quota limit definitions for an API.

    Args:
      limit_definitions: List of endpoints.LimitDefinition tuples

    Returns:
      A dict descriptor of the API's quota limit definitions.
    """
    if not limit_definitions:
      return None

    definitions_list = [{
        'name': ld.metric_name,
        'metric': ld.metric_name,
        'unit': '1/min/{project}',
        'values': {'STANDARD': ld.default_limit},
        'displayName': ld.display_name,
    } for ld in limit_definitions]

    metrics = [{
        'name': ld.metric_name,
        'valueType': 'INT64',
        'metricKind': 'GAUGE',
    } for ld in limit_definitions]

    return {
        'quota': {'limits': definitions_list},
        'metrics': metrics,
    }

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

    Args:
      service: endpoints.Service, Implementation of the API as a service.
      method_info: _MethodInfo, Configuration for the method.
      operation_id: string, Operation ID of the method
      protorpc_method_info: protorpc.remote._RemoteMethodInfo, ProtoRPC
        description of the method.
      security_definitions: list of dicts, security definitions for the API.

    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

    path = method_info.get_path(service.api_info)

    descriptor['parameters'] = self.__request_message_descriptor(
        request_kind, request_message_type,
        method_info.method_id(service.api_info),
        path)
    descriptor['responses'] = self.__response_message_descriptor(
        remote_method.response_type(), method_info.method_id(service.api_info))
    descriptor['operationId'] = operation_id

    # Insert the auth audiences, if any
    api_key_required = method_info.is_api_key_required(service.api_info)
    if method_info.audiences is not None:
      descriptor['security'] = self.__security_descriptor(
          method_info.audiences, security_definitions,
          api_key_required=api_key_required)
    elif service.api_info.audiences is not None or api_key_required:
      descriptor['security'] = self.__security_descriptor(
          service.api_info.audiences, security_definitions,
          api_key_required=api_key_required)

    # Insert the metric costs, if any
    if method_info.metric_costs:
      descriptor['x-google-quota'] = self.__x_google_quota_descriptor(
          method_info.metric_costs)

    return descriptor

  def __security_descriptor(self, audiences, security_definitions,
                            api_key_required=False):
    if not audiences:
      if not api_key_required:
        # no security
        return []
      # api key only
      return [{_API_KEY: []}]

    if isinstance(audiences, (tuple, list)):
      # security_definitions includes not just the base issuers, but also the
      # hash-appended versions, so we need to filter them out
      security_issuers = set()
      for definition_key in security_definitions.keys():
        if definition_key == _API_KEY:
          # API key definitions don't count for these purposes
          continue
        if '-' in definition_key:
          split_key = definition_key.rsplit('-', 1)[0]
          if split_key in security_definitions:
            continue
        security_issuers.add(definition_key)

      if security_issuers != {_DEFAULT_SECURITY_DEFINITION}:
        raise api_exceptions.ApiConfigurationError(
          'audiences must be a dict when third-party issuers '
          '(auth0, firebase, etc) are in use.'
        )
      audiences = {_DEFAULT_SECURITY_DEFINITION: audiences}

    results = []
    for issuer, issuer_audiences in audiences.items():
      result_dict = {}
      if issuer not in security_definitions:
        raise TypeError('Missing issuer {}'.format(issuer))
      audience_string = ','.join(sorted(issuer_audiences))
      audience_hash = hashfunc(audience_string)
      full_definition_key = '-'.join([issuer, audience_hash])
      result_dict[full_definition_key] = []
      if api_key_required:
        result_dict[_API_KEY] = []
      if full_definition_key not in security_definitions:
        new_definition = dict(security_definitions[issuer])
        new_definition['x-google-audiences'] = audience_string
        security_definitions[full_definition_key] = new_definition
      results.append(result_dict)

    return results

  def __security_definitions_descriptor(self, issuers):
    """Create a descriptor for the security definitions.

    Args:
      issuers: dict, mapping issuer names to Issuer tuples

    Returns:
      The dict representing the security definitions descriptor.
    """
    if not issuers:
      result = {
          _DEFAULT_SECURITY_DEFINITION: {
              'authorizationUrl': '',
              'flow': 'implicit',
              'type': 'oauth2',
              'x-google-issuer': 'https://accounts.google.com',
              'x-google-jwks_uri': 'https://www.googleapis.com/oauth2/v3/certs',
          }
      }
      return result

    result = {}

    for issuer_key, issuer_value in issuers.items():
      result[issuer_key] = {
          'authorizationUrl': '',
          'flow': 'implicit',
          'type': 'oauth2',
          'x-google-issuer': issuer_value.issuer,
      }

      # If jwks_uri is omitted, the auth library will use OpenID discovery
      # to find it. Otherwise, include it in the descriptor explicitly.
      if issuer_value.jwks_uri:
        result[issuer_key]['x-google-jwks_uri'] = issuer_value.jwks_uri

    return result

  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.

    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()).
    """
    merged_api_info = services[0].api_info

    # Verify that, if there are multiple classes here, they're allowed to
    # implement the same API.
    for service in services[1:]:
      if not merged_api_info.is_same_api(service.api_info):
        raise api_exceptions.ApiConfigurationError(
            _MULTICLASS_MISMATCH_ERROR_TEMPLATE % (service.api_info.name,
                                                   service.api_info.api_version))

    return merged_api_info

  def __api_openapi_descriptor(self, services, hostname=None, x_google_api_name=False):
    """Builds an OpenAPI description of 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 and stored as an API
      description document in OpenAPI 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,
                                              x_google_api_name=x_google_api_name)

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

    security_definitions = self.__security_definitions_descriptor(
        merged_api_info.issuers)

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

    for service in services:
      remote_methods = service.all_remote_methods()

      for protorpc_meth_name in sorted(remote_methods.keys()):
        protorpc_meth_info = remote_methods[protorpc_meth_name]
        method_info = getattr(protorpc_meth_info, 'method_info', None)
        # Skip methods that are not decorated with @method
        if method_info is None:
          continue
        method_id = method_info.method_id(service.api_info)
        is_api_key_required = method_info.is_api_key_required(service.api_info)
        path = '/{0}/{1}/{2}'.format(merged_api_info.name,
                                     merged_api_info.path_version,
                                     method_info.get_path(service.api_info))
        verb = method_info.http_method.lower()

        if path not in method_map:
          method_map[path] = {}

        # If an API key is required and the security definitions don't already
        # have the apiKey issuer, add the appropriate notation now
        if is_api_key_required and _API_KEY not in security_definitions:
          security_definitions[_API_KEY] = {
              'type': 'apiKey',
              'name': _API_KEY_PARAM,
              'in': 'query'
          }

        # Derive an OperationId from the method name data
        operation_id = self._construct_operation_id(
            service.__name__, protorpc_meth_name)

        method_map[path][verb] = self.__method_descriptor(
            service, method_info, operation_id, protorpc_meth_info,
            security_definitions)

        # 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,
                           method_info.get_path(service.api_info))
        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, method_info.get_path(service.api_info),
               rest_collision_tracker[rest_identifier],
               service.__name__))
        else:
          rest_collision_tracker[rest_identifier] = service.__name__

    if method_map:
      descriptor['paths'] = method_map

    # Add request and/or response definitions, if any
    definitions = self.__definitions_descriptor()
    if definitions:
      descriptor['definitions'] = definitions

    descriptor['securityDefinitions'] = security_definitions

    # Add quota limit metric definitions, if any
    limit_definitions = self.__x_google_quota_definitions_descriptor(
        merged_api_info.limit_definitions)
    if limit_definitions:
      descriptor['x-google-management'] = limit_definitions

    return descriptor

  def get_descriptor_defaults(self, api_info, hostname=None, x_google_api_name=False):
    """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.
    """
    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'
    base_path = api_info.base_path
    if base_path != '/':
        base_path = base_path.rstrip('/')
    defaults = {
        'swagger': '2.0',
        'info': {
            'version': api_info.api_version,
            'title': api_info.name
        },
        'host': hostname,
        'consumes': ['application/json'],
        'produces': ['application/json'],
        'schemes': [protocol],
        'basePath': base_path,
    }

    if x_google_api_name:
        defaults['x-google-api-name'] = _validate_api_name(api_info.name)

    return defaults

  def get_openapi_dict(self, services, hostname=None, x_google_api_name=False):
    """JSON dict description of a protorpc.remote.Service in OpenAPI 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 OpenAPI descriptor 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.__api_openapi_descriptor(services, hostname=hostname, x_google_api_name=x_google_api_name)

  def pretty_print_config_to_json(self, services, hostname=None, x_google_api_name=False):
    """JSON string description of a protorpc.remote.Service in OpenAPI 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:
      string, The OpenAPI descriptor document as a JSON string.
    """
    descriptor = self.get_openapi_dict(services, hostname, x_google_api_name=x_google_api_name)
    return json.dumps(descriptor, sort_keys=True, indent=2,
                      separators=(',', ': '))


def hashfunc(string):
    return hashlib.md5(string).hexdigest()[:8]
