# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""The metaclasses used by the mojo python bindings."""

import itertools
import logging
import sys

# pylint: disable=F0401
import mojo_bindings.messaging as messaging
import mojo_bindings.promise as promise
import mojo_bindings.serialization as serialization


class MojoEnumType(type):
  """Meta class for enumerations.

  Usage:
    class MyEnum(object):
      __metaclass__ = MojoEnumType
      VALUES = [
        ('A', 0),
        'B',
        ('C', 5),
      ]

      This will define a enum with 3 values, 'A' = 0, 'B' = 1 and 'C' = 5.
  """

  def __new__(mcs, name, bases, dictionary):
    dictionary['__slots__'] = ()
    dictionary['__new__'] = None
    for value in dictionary.pop('VALUES', []):
      if not isinstance(value, tuple):
        raise ValueError('incorrect value: %r' % value)
      key, enum_value = value
      if isinstance(key, str) and isinstance(enum_value, int):
        dictionary[key] = enum_value
      else:
        raise ValueError('incorrect value: %r' % value)
    return type.__new__(mcs, name, bases, dictionary)

  def __setattr__(cls, key, value):
    raise AttributeError('can\'t set attribute')

  def __delattr__(cls, key):
    raise AttributeError('can\'t delete attribute')


class MojoStructType(type):
  """Meta class for structs.

  Usage:
    class MyStruct(object):
      __metaclass__ = MojoStructType
      DESCRIPTOR = {
        'constants': {
          'C1': 1,
          'C2': 2,
        },
        'enums': {
          'ENUM1': [
            ('V1', 1),
            'V2',
          ],
          'ENUM2': [
            ('V1', 1),
            'V2',
          ],
        },
        'fields': [
           SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
        ],
      }

      This will define an struct, with:
      - 2 constants 'C1' and 'C2';
      - 2 enums 'ENUM1' and 'ENUM2', each of those having 2 values, 'V1' and
        'V2';
      - 1 int32 field named 'x'.
  """

  def __new__(mcs, name, bases, dictionary):
    dictionary['__slots__'] = ('_fields')
    descriptor = dictionary.pop('DESCRIPTOR', {})

    # Add constants
    dictionary.update(descriptor.get('constants', {}))

    # Add enums
    enums = descriptor.get('enums', {})
    for key in enums:
      dictionary[key] = MojoEnumType(key, (object,), { 'VALUES': enums[key] })

    # Add fields
    groups = descriptor.get('fields', [])

    fields = list(
        itertools.chain.from_iterable([group.descriptors for group in groups]))
    fields.sort(key=lambda f: f.index)
    for field in fields:
      dictionary[field.name] = _BuildProperty(field)

    # Add init
    dictionary['__init__'] = _StructInit(fields)

    # Add serialization method
    serialization_object = serialization.Serialization(groups)
    def Serialize(self, handle_offset=0):
      return serialization_object.Serialize(self, handle_offset)
    dictionary['Serialize'] = Serialize

    # pylint: disable=W0212
    def AsDict(self):
      return self._fields
    dictionary['AsDict'] = AsDict

    def Deserialize(cls, context):
      result = cls.__new__(cls)
      fields = {}
      serialization_object.Deserialize(fields, context)
      result._fields = fields
      return result
    dictionary['Deserialize'] = classmethod(Deserialize)

    dictionary['__eq__'] = _StructEq(fields)
    dictionary['__ne__'] = _StructNe

    return type.__new__(mcs, name, bases, dictionary)

  # Prevent adding new attributes, or mutating constants.
  def __setattr__(cls, key, value):
    raise AttributeError('can\'t set attribute')

  # Prevent deleting constants.
  def __delattr__(cls, key):
    raise AttributeError('can\'t delete attribute')


class MojoInterfaceType(type):
  """Meta class for interfaces.

  Usage:
    class MyInterface(object):
      __metaclass__ = MojoInterfaceType
      DESCRIPTOR = {
        'client': MyInterfaceClient,
        'methods': [
          {
            'name': 'FireAndForget',
            'ordinal': 0,
            'parameters': [
              SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
            ]
          },
          {
            'name': 'Ping',
            'ordinal': 1,
            'parameters': [
              SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
            ],
            'responses': [
              SingleFieldGroup('x', _descriptor.TYPE_INT32, 0, 0),
            ],
          },
        ],
      }
  """

  def __new__(mcs, name, bases, dictionary):
    # If one of the base class is already an interface type, do not edit the
    # class.
    for base in bases:
      if isinstance(base, mcs):
        return type.__new__(mcs, name, bases, dictionary)

    descriptor = dictionary.pop('DESCRIPTOR', {})

    methods = [_MethodDescriptor(x) for x in descriptor.get('methods', [])]
    for method in methods:
      dictionary[method.name] = _NotImplemented
    client_class_getter = descriptor.get('client', None)
    fully_qualified_name = descriptor['fully_qualified_name']

    interface_manager = InterfaceManager(fully_qualified_name, methods,
        client_class_getter)
    dictionary.update({
        'client': None,
        'manager': None,
        '_interface_manager': interface_manager,
    })

    interface_class = type.__new__(mcs, name, bases, dictionary)
    interface_manager.interface_class = interface_class
    return interface_class

  @property
  def manager(cls):
    return cls._interface_manager

  # Prevent adding new attributes, or mutating constants.
  def __setattr__(cls, key, value):
    raise AttributeError('can\'t set attribute')

  # Prevent deleting constants.
  def __delattr__(cls, key):
    raise AttributeError('can\'t delete attribute')


class InterfaceProxy(object):
  """
  A proxy allows to access a remote interface through a message pipe.
  """
  pass


class InterfaceRequest(object):
  """
  An interface request allows to send a request for an interface to a remote
  object and start using it immediately.
  """

  def __init__(self, handle):
    self._handle = handle

  def IsPending(self):
    return self._handle.IsValid()

  def PassMessagePipe(self):
    result = self._handle
    self._handle = None
    return result

  def Bind(self, impl):
    type(impl).manager.Bind(impl, self.PassMessagePipe())


class InterfaceManager(object):
  """
  Manager for an interface class. The manager contains the operation that allows
  to bind an implementation to a pipe, or to generate a proxy for an interface
  over a pipe.
  """

  def __init__(self, name, methods, client_class_getter):
    self.name = name
    self.methods = methods
    self.interface_class = None
    self._client_class_getter = client_class_getter
    self._client_manager = None
    self._client_manager_computed = False
    self._proxy_class = None
    self._stub_class = None

  @property
  def client_manager(self):
    if not self._client_manager_computed:
      self._client_manager_computed = True
      if self._client_class_getter:
        self._client_manager = self._client_class_getter().manager
    return self._client_manager

  def Proxy(self, handle):
    router = messaging.Router(handle)
    error_handler = _ProxyErrorHandler()
    router.SetErrorHandler(error_handler)
    router.Start()
    return self._InternalProxy(router, error_handler)

  # pylint: disable=W0212
  def Bind(self, impl, handle):
    router = messaging.Router(handle)
    router.SetIncomingMessageReceiver(self._Stub(impl))
    error_handler = _ProxyErrorHandler()
    router.SetErrorHandler(error_handler)

    # Retain the router, until an error happen.
    retainer = _Retainer(router)
    def Cleanup(_):
      retainer.release()
    error_handler.AddCallback(Cleanup)

    if self.client_manager:
      impl.client = self.client_manager._InternalProxy(router, error_handler)

    # Give an instance manager to the implementation to allow it to close
    # the connection.
    impl.manager = InstanceManager(router, error_handler)

    router.Start()

  def _InternalProxy(self, router, error_handler):
    if not self._proxy_class:
      dictionary = {
        '__module__': __name__,
        '__init__': _ProxyInit,
      }
      if self.client_manager:
        dictionary['client'] = property(_ProxyGetClient, _ProxySetClient)
        dictionary['manager'] = None
        dictionary['_client_manager'] = self.client_manager
      for method in self.methods:
        dictionary[method.name] = _ProxyMethodCall(method)
      self._proxy_class = type('%sProxy' % self.name,
                               (self.interface_class, InterfaceProxy),
                               dictionary)

    proxy = self._proxy_class(router, error_handler)
    # Give an instance manager to the proxy to allow to close the connection.
    proxy.manager = InstanceManager(router, error_handler)
    return proxy

  def _Stub(self, impl):
    if not self._stub_class:
      accept_method = _StubAccept(self.methods)
      dictionary = {
        '__module__': __name__,
        '__init__': _StubInit,
        'Accept': accept_method,
        'AcceptWithResponder': accept_method,
      }
      self._stub_class = type('%sStub' % self.name,
                              (messaging.MessageReceiverWithResponder,),
                              dictionary)
    return self._stub_class(impl)


class InstanceManager(object):
  """
  Manager for the implementation of an interface or a proxy. The manager allows
  to control the connection over the pipe.
  """
  def __init__(self, router, error_handler):
    self._router = router
    self._error_handler = error_handler

  def Close(self):
    self._router.Close()

  def PassMessagePipe(self):
    return self._router.PassMessagePipe()

  def AddOnErrorCallback(self, callback):
    self._error_handler.AddCallback(lambda _: callback())


class _MethodDescriptor(object):
  def __init__(self, descriptor):
    self.name = descriptor['name']
    self.ordinal = descriptor['ordinal']
    self.parameters_struct = _ConstructParameterStruct(
        descriptor['parameters'], self.name, "Parameters")
    self.response_struct = _ConstructParameterStruct(
        descriptor.get('responses'), self.name, "Responses")


def _ConstructParameterStruct(descriptor, name, suffix):
  if descriptor is None:
    return None
  parameter_dictionary = {
    '__metaclass__': MojoStructType,
    '__module__': __name__,
    'DESCRIPTOR': descriptor,
  }
  return MojoStructType(
      '%s%s' % (name, suffix),
      (object,),
      parameter_dictionary)


class _ProxyErrorHandler(messaging.ConnectionErrorHandler):
  def __init__(self):
    messaging.ConnectionErrorHandler.__init__(self)
    self._callbacks = set()

  def OnError(self, result):
    exception = messaging.MessagingException('Mojo error: %d' % result)
    for callback in list(self._callbacks):
      callback(exception)
    self._callbacks = None

  def AddCallback(self, callback):
    if self._callbacks is not None:
      self._callbacks.add(callback)

  def RemoveCallback(self, callback):
    if self._callbacks:
      self._callbacks.remove(callback)


class _Retainer(object):

  # Set to force instances to be retained.
  _RETAINED = set()

  def __init__(self, retained):
    self._retained = retained
    _Retainer._RETAINED.add(self)

  def release(self):
    self._retained = None
    _Retainer._RETAINED.remove(self)


def _StructInit(fields):
  def _Init(self, *args, **kwargs):
    if len(args) + len(kwargs) > len(fields):
      raise TypeError('__init__() takes %d argument (%d given)' %
                      (len(fields), len(args) + len(kwargs)))
    self._fields = {}
    for f, a in zip(fields, args):
      self.__setattr__(f.name, a)
    remaining_fields = set(x.name for x in fields[len(args):])
    for name in kwargs:
      if not name in remaining_fields:
        if name in (x.name for x in fields[:len(args)]):
          raise TypeError(
              '__init__() got multiple values for keyword argument %r' % name)
        raise TypeError('__init__() got an unexpected keyword argument %r' %
                        name)
      self.__setattr__(name, kwargs[name])
  return _Init


def _BuildProperty(field):
  """Build the property for the given field."""

  # pylint: disable=W0212
  def Get(self):
    if field.name not in self._fields:
      self._fields[field.name] = field.GetDefaultValue()
    return self._fields[field.name]

  # pylint: disable=W0212
  def Set(self, value):
    self._fields[field.name] = field.field_type.Convert(value)

  return property(Get, Set)


def _StructEq(fields):
  def _Eq(self, other):
    if type(self) is not type(other):
      return False
    for field in fields:
      if getattr(self, field.name) != getattr(other, field.name):
        return False
    return True
  return _Eq

def _StructNe(self, other):
  return not self.__eq__(other)


def _ProxyInit(self, router, error_handler):
  self._router = router
  self._error_handler = error_handler
  self._client = None


# pylint: disable=W0212
def _ProxyGetClient(self):
  return self._client


# pylint: disable=W0212
def _ProxySetClient(self, client):
  self._client = client
  stub = self._client_manager._Stub(client)
  self._router.SetIncomingMessageReceiver(stub)


# pylint: disable=W0212
def _ProxyMethodCall(method):
  flags = messaging.NO_FLAG
  if method.response_struct:
    flags = messaging.MESSAGE_EXPECTS_RESPONSE_FLAG
  def _Call(self, *args, **kwargs):
    def GenerationMethod(resolve, reject):
      message = _GetMessage(method, flags, *args, **kwargs)
      if method.response_struct:
        def Accept(message):
          try:
            assert message.header.message_type == method.ordinal
            payload = message.payload
            response = method.response_struct.Deserialize(
                serialization.RootDeserializationContext(payload.data,
                                                         payload.handles))
            as_dict = response.AsDict()
            if len(as_dict) == 1:
              value = as_dict.values()[0]
              if not isinstance(value, dict):
                response = value
            resolve(response)
            return True
          except Exception as e:
            # Adding traceback similarly to python 3.0 (pep-3134)
            e.__traceback__ = sys.exc_info()[2]
            reject(e)
            return False
          finally:
            self._error_handler.RemoveCallback(reject)

        self._error_handler.AddCallback(reject)
        if not self._router.AcceptWithResponder(
            message, messaging.ForwardingMessageReceiver(Accept)):
          self._error_handler.RemoveCallback(reject)
          reject(messaging.MessagingException("Unable to send message."))
      else:
        if (self._router.Accept(message)):
          resolve(None)
        else:
          reject(messaging.MessagingException("Unable to send message."))
    return promise.Promise(GenerationMethod)
  return _Call


def _GetMessage(method, flags, *args, **kwargs):
  if flags == messaging.MESSAGE_IS_RESPONSE_FLAG:
    struct = method.response_struct(*args, **kwargs)
  else:
    struct = method.parameters_struct(*args, **kwargs)
  header = messaging.MessageHeader(method.ordinal, flags)
  data = header.Serialize()
  (payload, handles) = struct.Serialize()
  data.extend(payload)
  return messaging.Message(data, handles, header)


def _StubInit(self, impl):
  self.impl = impl


def _StubAccept(methods):
  methods_by_ordinal = dict((m.ordinal, m) for m in methods)
  def Accept(self, message, responder=None):
    try:
      header = message.header
      assert header.expects_response == bool(responder)
      assert header.message_type in methods_by_ordinal
      method = methods_by_ordinal[header.message_type]
      payload = message.payload
      parameters = method.parameters_struct.Deserialize(
          serialization.RootDeserializationContext(
              payload.data, payload.handles)).AsDict()
      response = getattr(self.impl, method.name)(**parameters)
      if header.expects_response:
        def SendResponse(response):
          if isinstance(response, dict):
            response_message = _GetMessage(method,
                                           messaging.MESSAGE_IS_RESPONSE_FLAG,
                                           **response)
          else:
            response_message = _GetMessage(method,
                                           messaging.MESSAGE_IS_RESPONSE_FLAG,
                                           response)
          response_message.header.request_id = header.request_id
          responder.Accept(response_message)
        p = promise.Promise.Resolve(response).Then(SendResponse)
        if self.impl.manager:
          # Close the connection in case of error.
          p.Catch(lambda _: self.impl.manager.Close())
      return True
    # pylint: disable=W0702
    except:
      # Close the connection in case of error.
      logging.warning(
          'Error occured in accept method. Connection will be closed.')
      if self.impl.manager:
        self.impl.manager.Close()
      return False
  return Accept


def _NotImplemented(*_1, **_2):
  raise NotImplementedError()
