#!/usr/bin/env python
#
# Copyright 2010 Google Inc.
#
# 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.
#

"""Services descriptor definitions.

Contains message definitions and functions for converting
service classes into transmittable message format.

Describing an Enum instance, Enum class, Field class or Message class will
generate an appropriate descriptor object that describes that class.
This message can itself be used to transmit information to clients wishing
to know the description of an enum value, enum, field or message without
needing to download the source code.  This format is also compatible with
other, non-Python languages.

The descriptors are modeled to be binary compatible with:

  http://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto

NOTE: The names of types and fields are not always the same between these
descriptors and the ones defined in descriptor.proto.  This was done in order
to make source code files that use these descriptors easier to read.  For
example, it is not necessary to prefix TYPE to all the values in
FieldDescriptor.Variant as is done in descriptor.proto FieldDescriptorProto.Type.

Example:

  class Pixel(messages.Message):

    x = messages.IntegerField(1, required=True)
    y = messages.IntegerField(2, required=True)

    color = messages.BytesField(3)

  # Describe Pixel class using message descriptor.
  fields = []

  field = FieldDescriptor()
  field.name = 'x'
  field.number = 1
  field.label = FieldDescriptor.Label.REQUIRED
  field.variant = FieldDescriptor.Variant.INT64
  fields.append(field)

  field = FieldDescriptor()
  field.name = 'y'
  field.number = 2
  field.label = FieldDescriptor.Label.REQUIRED
  field.variant = FieldDescriptor.Variant.INT64
  fields.append(field)

  field = FieldDescriptor()
  field.name = 'color'
  field.number = 3
  field.label = FieldDescriptor.Label.OPTIONAL
  field.variant = FieldDescriptor.Variant.BYTES
  fields.append(field)

  message = MessageDescriptor()
  message.name = 'Pixel'
  message.fields = fields

  # Describing is the equivalent of building the above message.
  message == describe_message(Pixel)

Public Classes:
  EnumValueDescriptor: Describes Enum values.
  EnumDescriptor: Describes Enum classes.
  FieldDescriptor: Describes field instances.
  FileDescriptor: Describes a single 'file' unit.
  FileSet: Describes a collection of file descriptors.
  MessageDescriptor: Describes Message classes.
  MethodDescriptor: Describes a method of a service.
  ServiceDescriptor: Describes a services.

Public Functions:
  describe_enum_value: Describe an individual enum-value.
  describe_enum: Describe an Enum class.
  describe_field: Describe a Field definition.
  describe_file: Describe a 'file' unit from a Python module or object.
  describe_file_set: Describe a file set from a list of modules or objects.
  describe_message: Describe a Message definition.
  describe_method: Describe a Method definition.
  describe_service: Describe a Service definition.
"""
import six

__author__ = 'rafek@google.com (Rafe Kaplan)'

import codecs
import types

from . import messages
from . import util


__all__ = ['EnumDescriptor',
           'EnumValueDescriptor',
           'FieldDescriptor',
           'MessageDescriptor',
           'MethodDescriptor',
           'FileDescriptor',
           'FileSet',
           'ServiceDescriptor',
           'DescriptorLibrary',

           'describe_enum',
           'describe_enum_value',
           'describe_field',
           'describe_message',
           'describe_method',
           'describe_file',
           'describe_file_set',
           'describe_service',
           'describe',
           'import_descriptor_loader',
          ]


# NOTE: MessageField is missing because message fields cannot have
# a default value at this time.
# TODO(rafek): Support default message values.
#
# Map to functions that convert default values of fields of a given type
# to a string.  The function must return a value that is compatible with
# FieldDescriptor.default_value and therefore a unicode string.
_DEFAULT_TO_STRING_MAP = {
    messages.IntegerField: six.text_type,
    messages.FloatField: six.text_type,
    messages.BooleanField: lambda value: value and u'true' or u'false',
    messages.BytesField: lambda value: codecs.escape_encode(value)[0],
    messages.StringField: lambda value: value,
    messages.EnumField: lambda value: six.text_type(value.number),
}

_DEFAULT_FROM_STRING_MAP = {
    messages.IntegerField: int,
    messages.FloatField: float,
    messages.BooleanField: lambda value: value == u'true',
    messages.BytesField: lambda value: codecs.escape_decode(value)[0],
    messages.StringField: lambda value: value,
    messages.EnumField: int,
}


class EnumValueDescriptor(messages.Message):
  """Enum value descriptor.

  Fields:
    name: Name of enumeration value.
    number: Number of enumeration value.
  """

  # TODO(rafek): Why are these listed as optional in descriptor.proto.
  # Harmonize?
  name = messages.StringField(1, required=True)
  number = messages.IntegerField(2,
                                 required=True,
                                 variant=messages.Variant.INT32)


class EnumDescriptor(messages.Message):
  """Enum class descriptor.

  Fields:
    name: Name of Enum without any qualification.
    values: Values defined by Enum class.
  """

  name = messages.StringField(1)
  values = messages.MessageField(EnumValueDescriptor, 2, repeated=True)


class FieldDescriptor(messages.Message):
  """Field definition descriptor.

  Enums:
    Variant: Wire format hint sub-types for field.
    Label: Values for optional, required and repeated fields.

  Fields:
    name: Name of field.
    number: Number of field.
    variant: Variant of field.
    type_name: Type name for message and enum fields.
    default_value: String representation of default value.
  """

  Variant = messages.Variant

  class Label(messages.Enum):
    """Field label."""

    OPTIONAL = 1
    REQUIRED = 2
    REPEATED = 3

  name = messages.StringField(1, required=True)
  number = messages.IntegerField(3,
                                 required=True,
                                 variant=messages.Variant.INT32)
  label = messages.EnumField(Label, 4, default=Label.OPTIONAL)
  variant = messages.EnumField(Variant, 5)
  type_name = messages.StringField(6)

  # For numeric types, contains the original text representation of the value.
  # For booleans, "true" or "false".
  # For strings, contains the default text contents (not escaped in any way).
  # For bytes, contains the C escaped value.  All bytes < 128 are that are
  #   traditionally considered unprintable are also escaped.
  default_value = messages.StringField(7)


class MessageDescriptor(messages.Message):
  """Message definition descriptor.

  Fields:
    name: Name of Message without any qualification.
    fields: Fields defined for message.
    message_types: Nested Message classes defined on message.
    enum_types: Nested Enum classes defined on message.
  """

  name = messages.StringField(1)
  fields = messages.MessageField(FieldDescriptor, 2, repeated=True)

  message_types = messages.MessageField(
    'protorpc.descriptor.MessageDescriptor', 3, repeated=True)
  enum_types = messages.MessageField(EnumDescriptor, 4, repeated=True)


class MethodDescriptor(messages.Message):
  """Service method definition descriptor.

  Fields:
    name: Name of service method.
    request_type: Fully qualified or relative name of request message type.
    response_type: Fully qualified or relative name of response message type.
  """

  name = messages.StringField(1)

  request_type = messages.StringField(2)
  response_type = messages.StringField(3)


class ServiceDescriptor(messages.Message):
  """Service definition descriptor.

  Fields:
    name: Name of Service without any qualification.
    methods: Remote methods of Service.
  """

  name = messages.StringField(1)

  methods = messages.MessageField(MethodDescriptor, 2, repeated=True)


class FileDescriptor(messages.Message):
  """Description of file containing protobuf definitions.

  Fields:
    package: Fully qualified name of package that definitions belong to.
    message_types: Message definitions contained in file.
    enum_types: Enum definitions contained in file.
    service_types: Service definitions contained in file.
  """

  package = messages.StringField(2)

  # TODO(rafek): Add dependency field

  message_types = messages.MessageField(MessageDescriptor, 4, repeated=True)
  enum_types = messages.MessageField(EnumDescriptor, 5, repeated=True)
  service_types = messages.MessageField(ServiceDescriptor, 6, repeated=True)


class FileSet(messages.Message):
  """A collection of FileDescriptors.

  Fields:
    files: Files in file-set.
  """

  files = messages.MessageField(FileDescriptor, 1, repeated=True)


def describe_enum_value(enum_value):
  """Build descriptor for Enum instance.

  Args:
    enum_value: Enum value to provide descriptor for.

  Returns:
    Initialized EnumValueDescriptor instance describing the Enum instance.
  """
  enum_value_descriptor = EnumValueDescriptor()
  enum_value_descriptor.name = six.text_type(enum_value.name)
  enum_value_descriptor.number = enum_value.number
  return enum_value_descriptor


def describe_enum(enum_definition):
  """Build descriptor for Enum class.

  Args:
    enum_definition: Enum class to provide descriptor for.

  Returns:
    Initialized EnumDescriptor instance describing the Enum class.
  """
  enum_descriptor = EnumDescriptor()
  enum_descriptor.name = enum_definition.definition_name().split('.')[-1]

  values = []
  for number in enum_definition.numbers():
    value = enum_definition.lookup_by_number(number)
    values.append(describe_enum_value(value))

  if values:
    enum_descriptor.values = values

  return enum_descriptor


def describe_field(field_definition):
  """Build descriptor for Field instance.

  Args:
    field_definition: Field instance to provide descriptor for.

  Returns:
    Initialized FieldDescriptor instance describing the Field instance.
  """
  field_descriptor = FieldDescriptor()
  field_descriptor.name = field_definition.name
  field_descriptor.number = field_definition.number
  field_descriptor.variant = field_definition.variant

  if isinstance(field_definition, messages.EnumField):
    field_descriptor.type_name = field_definition.type.definition_name()

  if isinstance(field_definition, messages.MessageField):
    field_descriptor.type_name = field_definition.message_type.definition_name()

  if field_definition.default is not None:
    field_descriptor.default_value = _DEFAULT_TO_STRING_MAP[
        type(field_definition)](field_definition.default)

  # Set label.
  if field_definition.repeated:
    field_descriptor.label = FieldDescriptor.Label.REPEATED
  elif field_definition.required:
    field_descriptor.label = FieldDescriptor.Label.REQUIRED
  else:
    field_descriptor.label = FieldDescriptor.Label.OPTIONAL

  return field_descriptor


def describe_message(message_definition):
  """Build descriptor for Message class.

  Args:
    message_definition: Message class to provide descriptor for.

  Returns:
    Initialized MessageDescriptor instance describing the Message class.
  """
  message_descriptor = MessageDescriptor()
  message_descriptor.name = message_definition.definition_name().split('.')[-1]

  fields = sorted(message_definition.all_fields(),
                  key=lambda v: v.number)
  if fields:
    message_descriptor.fields = [describe_field(field) for field in fields]

  try:
    nested_messages = message_definition.__messages__
  except AttributeError:
    pass
  else:
    message_descriptors = []
    for name in nested_messages:
      value = getattr(message_definition, name)
      message_descriptors.append(describe_message(value))

    message_descriptor.message_types = message_descriptors

  try:
    nested_enums = message_definition.__enums__
  except AttributeError:
    pass
  else:
    enum_descriptors = []
    for name in nested_enums:
      value = getattr(message_definition, name)
      enum_descriptors.append(describe_enum(value))

    message_descriptor.enum_types = enum_descriptors

  return message_descriptor


def describe_method(method):
  """Build descriptor for service method.

  Args:
    method: Remote service method to describe.

  Returns:
    Initialized MethodDescriptor instance describing the service method.
  """
  method_info = method.remote
  descriptor = MethodDescriptor()
  descriptor.name = method_info.method.__name__
  descriptor.request_type = method_info.request_type.definition_name()
  descriptor.response_type = method_info.response_type.definition_name()

  return descriptor


def describe_service(service_class):
  """Build descriptor for service.

  Args:
    service_class: Service class to describe.

  Returns:
    Initialized ServiceDescriptor instance describing the service.
  """
  descriptor = ServiceDescriptor()
  descriptor.name = service_class.__name__
  methods = []
  remote_methods = service_class.all_remote_methods()
  for name in sorted(remote_methods.keys()):
    if name == 'get_descriptor':
      continue

    method = remote_methods[name]
    methods.append(describe_method(method))
  if methods:
    descriptor.methods = methods

  return descriptor


def describe_file(module):
  """Build a file from a specified Python module.

  Args:
    module: Python module to describe.

  Returns:
    Initialized FileDescriptor instance describing the module.
  """
  # May not import remote at top of file because remote depends on this
  # file
  # TODO(rafek): Straighten out this dependency.  Possibly move these functions
  # from descriptor to their own module.
  from . import remote

  descriptor = FileDescriptor()
  descriptor.package = util.get_package_for_module(module)

  if not descriptor.package:
    descriptor.package = None

  message_descriptors = []
  enum_descriptors = []
  service_descriptors = []

  # Need to iterate over all top level attributes of the module looking for
  # message, enum and service definitions.  Each definition must be itself
  # described.
  for name in sorted(dir(module)):
    value = getattr(module, name)

    if isinstance(value, type):
      if issubclass(value, messages.Message):
        message_descriptors.append(describe_message(value))

      elif issubclass(value, messages.Enum):
        enum_descriptors.append(describe_enum(value))

      elif issubclass(value, remote.Service):
        service_descriptors.append(describe_service(value))

  if message_descriptors:
    descriptor.message_types = message_descriptors

  if enum_descriptors:
    descriptor.enum_types = enum_descriptors

  if service_descriptors:
    descriptor.service_types = service_descriptors

  return descriptor


def describe_file_set(modules):
  """Build a file set from a specified Python modules.

  Args:
    modules: Iterable of Python module to describe.

  Returns:
    Initialized FileSet instance describing the modules.
  """
  descriptor = FileSet()
  file_descriptors = []
  for module in modules:
    file_descriptors.append(describe_file(module))

  if file_descriptors:
    descriptor.files = file_descriptors

  return descriptor


def describe(value):
  """Describe any value as a descriptor.

  Helper function for describing any object with an appropriate descriptor
  object.

  Args:
    value: Value to describe as a descriptor.

  Returns:
    Descriptor message class if object is describable as a descriptor, else
    None.
  """
  from . import remote
  if isinstance(value, types.ModuleType):
    return describe_file(value)
  elif callable(value) and hasattr(value, 'remote'):
    return describe_method(value)
  elif isinstance(value, messages.Field):
    return describe_field(value)
  elif isinstance(value, messages.Enum):
    return describe_enum_value(value)
  elif isinstance(value, type):
    if issubclass(value, messages.Message):
      return describe_message(value)
    elif issubclass(value, messages.Enum):
      return describe_enum(value)
    elif issubclass(value, remote.Service):
      return describe_service(value)
  return None


@util.positional(1)
def import_descriptor_loader(definition_name, importer=__import__):
  """Find objects by importing modules as needed.

  A definition loader is a function that resolves a definition name to a
  descriptor.

  The import finder resolves definitions to their names by importing modules
  when necessary.

  Args:
    definition_name: Name of definition to find.
    importer: Import function used for importing new modules.

  Returns:
    Appropriate descriptor for any describable type located by name.

  Raises:
    DefinitionNotFoundError when a name does not refer to either a definition
    or a module.
  """
  # Attempt to import descriptor as a module.
  if definition_name.startswith('.'):
    definition_name = definition_name[1:]
  if not definition_name.startswith('.'):
    leaf = definition_name.split('.')[-1]
    if definition_name:
      try:
        module = importer(definition_name, '', '', [leaf])
      except ImportError:
        pass
      else:
        return describe(module)

  try:
    # Attempt to use messages.find_definition to find item.
    return describe(messages.find_definition(definition_name,
                                             importer=__import__))
  except messages.DefinitionNotFoundError as err:
    # There are things that find_definition will not find, but if the parent
    # is loaded, its children can be searched for a match.
    split_name = definition_name.rsplit('.', 1)
    if len(split_name) > 1:
      parent, child = split_name
      try:
        parent_definition = import_descriptor_loader(parent, importer=importer)
      except messages.DefinitionNotFoundError:
        # Fall through to original error.
        pass
      else:
        # Check the parent definition for a matching descriptor.
        if isinstance(parent_definition, FileDescriptor):
          search_list = parent_definition.service_types or []
        elif isinstance(parent_definition, ServiceDescriptor):
          search_list = parent_definition.methods or []
        elif isinstance(parent_definition, EnumDescriptor):
          search_list = parent_definition.values or []
        elif isinstance(parent_definition, MessageDescriptor):
          search_list = parent_definition.fields or []
        else:
          search_list = []

        for definition in search_list:
          if definition.name == child:
            return definition

    # Still didn't find.  Reraise original exception.
    raise err


class DescriptorLibrary(object):
  """A descriptor library is an object that contains known definitions.

  A descriptor library contains a cache of descriptor objects mapped by
  definition name.  It contains all types of descriptors except for
  file sets.

  When a definition name is requested that the library does not know about
  it can be provided with a descriptor loader which attempt to resolve the
  missing descriptor.
  """

  @util.positional(1)
  def __init__(self,
               descriptors=None,
               descriptor_loader=import_descriptor_loader):
    """Constructor.

    Args:
      descriptors: A dictionary or dictionary-like object that can be used
        to store and cache descriptors by definition name.
      definition_loader: A function used for resolving missing descriptors.
        The function takes a definition name as its parameter and returns
        an appropriate descriptor.  It may raise DefinitionNotFoundError.
    """
    self.__descriptor_loader = descriptor_loader
    self.__descriptors = descriptors or {}

  def lookup_descriptor(self, definition_name):
    """Lookup descriptor by name.

    Get descriptor from library by name.  If descriptor is not found will
    attempt to find via descriptor loader if provided.

    Args:
      definition_name: Definition name to find.

    Returns:
      Descriptor that describes definition name.

    Raises:
      DefinitionNotFoundError if not descriptor exists for definition name.
    """
    try:
      return self.__descriptors[definition_name]
    except KeyError:
      pass

    if self.__descriptor_loader:
      definition = self.__descriptor_loader(definition_name)
      self.__descriptors[definition_name] = definition
      return definition
    else:  
      raise messages.DefinitionNotFoundError(
        'Could not find definition for %s' % definition_name)

  def lookup_package(self, definition_name):
    """Determines the package name for any definition.

    Determine the package that any definition name belongs to.  May check
    parent for package name and will resolve missing descriptors if provided
    descriptor loader.

    Args:
      definition_name: Definition name to find package for.
    """
    while True:
      descriptor = self.lookup_descriptor(definition_name)
      if isinstance(descriptor, FileDescriptor):
        return descriptor.package
      else:
        index = definition_name.rfind('.')
        if index < 0:
          return None
        definition_name = definition_name[:index]
