# 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 descriptors used to define generated elements of the mojo python bindings.
"""

import array
import itertools
import struct

import mojo_bindings.reflection as reflection
import mojo_bindings.serialization as serialization

# pylint: disable=E0611,F0401
import mojo_system


class Type(object):
  """Describes the type of a struct field or a method parameter,"""

  def Convert(self, value): # pylint: disable=R0201
    """
    Convert the given value into its canonical representation, raising an
    exception if the value cannot be converted.
    """
    return value

  def GetDefaultValue(self, value):
    """
    Returns the default value for this type associated with the given value.
    This method must be able to correcly handle value being None.
    """
    return self.Convert(value)

  def IsUnion(self):
    """
    Returns true if the type is a union. This is necessary to be able to
    identify a union when descriptor.py cannot be imported.
    """
    return False


class SerializableType(Type):
  """Describe a type that can be serialized by itself."""

  def __init__(self, typecode):
    Type.__init__(self)
    self.typecode = typecode
    self.byte_size = struct.calcsize('<%s' % self.GetTypeCode())

  def GetTypeCode(self):
    """
    Returns the type code (as defined by the struct module) used to encode
    this type.
    """
    return self.typecode

  def GetByteSize(self):
    """
    Returns the size of the encoding of this type.
    """
    return self.byte_size

  def GetAlignment(self):
    """
    Returns the alignment required by the encoding of this type. By default it
    is set to the byte size of the biggest packed value.
    """
    return max([struct.calcsize('<%s' % c) for c in self.GetTypeCode()])

  def Serialize(self, value, data_offset, data, handle_offset):
    """
    Serialize a value of this type.

    Args:
      value: the value to serialize.
      data_offset: the offset to the end of the data bytearray. Used to encode
                   pointers.
      data: the bytearray to append additional data to.
      handle_offset: the offset to use to encode handles.

    Returns a a tuple where the first element is the value to encode, and the
    second is the array of handles to add to the message.
    """
    raise NotImplementedError()

  def Deserialize(self, value, context):
    """
    Deserialize a value of this type.

    Args:
      value: the base value for this type. This is always a numeric type, and
             corresponds to the first element in the tuple returned by
             Serialize.
      data: the bytearray to retrieve additional data from.
      handles: the array of handles contained in the message to deserialize.

    Returns the deserialized value.
    """
    raise NotImplementedError()


class BooleanType(SerializableType):
  """Type object for booleans"""

  def Convert(self, value):
    return bool(value)

  def Serialize(self, value, data_offset, data, handle_offset):
    return (_ConvertBooleansToByte([value]), [])

  def Deserialize(self, value, context):
    return _ConvertByteToBooleans(value, 1)[0]


class NumericType(SerializableType):
  """Base Type object for all numeric types"""

  def GetDefaultValue(self, value):
    if value is None:
      return self.Convert(0)
    return self.Convert(value)

  def Serialize(self, value, data_offset, data, handle_offset):
    return (value, [])

  def Deserialize(self, value, context):
    return value


class IntegerType(NumericType):
  """Type object for integer types."""

  def __init__(self, typecode):
    NumericType.__init__(self, typecode)
    size = 8 * self.byte_size
    signed = typecode.islower()
    if signed:
      self._min_value = -(1 << (size - 1))
      self._max_value = (1 << (size - 1)) - 1
    else:
      self._min_value = 0
      self._max_value = (1 << size) - 1

  def Convert(self, value):
    if value is None:
      raise TypeError('None is not an integer.')
    if not isinstance(value, (int, long)):
      raise TypeError('%r is not an integer type' % value)
    if value < self._min_value or value > self._max_value:
      raise OverflowError('%r is not in the range [%d, %d]' %
                          (value, self._min_value, self._max_value))
    return value


class FloatType(NumericType):
  """Type object for floating point number types."""

  def Convert(self, value):
    if value is None:
      raise TypeError('None is not an floating point number.')
    if not isinstance(value, (int, long, float)):
      raise TypeError('%r is not a numeric type' % value)
    return float(value)


class UnionType(SerializableType):
  """Base Type object for union."""

  def __init__(self, union_type_getter, nullable=False):
    SerializableType.__init__(self, 'IIQ')
    self.nullable = nullable
    self._union_type_getter = union_type_getter
    self._union_type = None

  def IsUnion(self):
    return True

  @property
  def union_type(self):
    if not self._union_type:
      self._union_type = self._union_type_getter()
    return self._union_type

  def Serialize(self, value, data_offset, data, handle_offset):
    if not value:
      if not self.nullable:
        raise serialization.SerializationException(
            'Trying to serialize null for non nullable type.')
      return ((0, 0, 0), [])

    ((size, tag, entry, new_data), new_handles) = (
        value.SerializeInline(handle_offset))
    if len(new_data) > 0:
      data.extend(new_data)
      entry = data_offset - 8

    return ((size, tag, entry), new_handles)

  def Deserialize(self, value, context):
    result = self.union_type.Deserialize(context)
    if not result and not self.nullable:
      raise serialization.DeserializationException(
          'Trying to deserialize null for non nullable type.')
    return result


class PointerType(SerializableType):
  """Base Type object for pointers."""

  def __init__(self, nullable=False):
    SerializableType.__init__(self, 'Q')
    self.nullable = nullable

  def Serialize(self, value, data_offset, data, handle_offset):
    if value is None and not self.nullable:
      raise serialization.SerializationException(
          'Trying to serialize null for non nullable type.')
    if value is None:
      return (0, [])
    return self.SerializePointer(value, data_offset, data, handle_offset)

  def Deserialize(self, value, context):
    if value == 0:
      if not self.nullable:
        raise serialization.DeserializationException(
            'Trying to deserialize null for non nullable type.')
      return None
    if value % 8 != 0:
      raise serialization.DeserializationException(
          'Pointer alignment is incorrect.')
    sub_context = context.GetSubContext(value)
    if len(sub_context.data) < serialization.HEADER_STRUCT.size:
      raise serialization.DeserializationException(
          'Available data too short to contain header.')
    (size, nb_elements) = serialization.HEADER_STRUCT.unpack_from(
        sub_context.data)
    if len(sub_context.data) < size or size < serialization.HEADER_STRUCT.size:
      raise serialization.DeserializationException('Header size is incorrect.')
    sub_context.ClaimMemory(0, size)
    return self.DeserializePointer(size, nb_elements, sub_context)

  def SerializePointer(self, value, data_offset, data, handle_offset):
    """Serialize the not null value."""
    raise NotImplementedError()

  def DeserializePointer(self, size, nb_elements, context):
    raise NotImplementedError()


class StringType(PointerType):
  """
  Type object for strings.

  Strings are represented as unicode, and the conversion is done using the
  default encoding if a string instance is used.
  """

  def __init__(self, nullable=False):
    PointerType.__init__(self, nullable)
    self._array_type = NativeArrayType('B', nullable)

  def Convert(self, value):
    if value is None or isinstance(value, unicode):
      return value
    if isinstance(value, str):
      return unicode(value)
    raise TypeError('%r is not a string' % value)

  def SerializePointer(self, value, data_offset, data, handle_offset):
    string_array = array.array('b')
    string_array.fromstring(value.encode('utf8'))
    return self._array_type.SerializeArray(
        string_array, data_offset, data, handle_offset)

  def DeserializePointer(self, size, nb_elements, context):
    string_array = self._array_type.DeserializeArray(size, nb_elements, context)
    return unicode(string_array.tostring(), 'utf8')


class BaseHandleType(SerializableType):
  """Type object for handles."""

  def __init__(self, nullable=False, type_code='i'):
    SerializableType.__init__(self, type_code)
    self.nullable = nullable

  def Serialize(self, value, data_offset, data, handle_offset):
    handle = self.ToHandle(value)
    if not handle.IsValid() and not self.nullable:
      raise serialization.SerializationException(
          'Trying to serialize null for non nullable type.')
    if not handle.IsValid():
      return (-1, [])
    return (handle_offset, [handle])

  def Deserialize(self, value, context):
    if value == -1:
      if not self.nullable:
        raise serialization.DeserializationException(
            'Trying to deserialize null for non nullable type.')
      return self.FromHandle(mojo_system.Handle())
    return self.FromHandle(context.ClaimHandle(value))

  def FromHandle(self, handle):
    raise NotImplementedError()

  def ToHandle(self, value):
    raise NotImplementedError()


class HandleType(BaseHandleType):
  """Type object for handles."""

  def Convert(self, value):
    if value is None:
      return mojo_system.Handle()
    if not isinstance(value, mojo_system.Handle):
      raise TypeError('%r is not a handle' % value)
    return value

  def FromHandle(self, handle):
    return handle

  def ToHandle(self, value):
    return value


class InterfaceRequestType(BaseHandleType):
  """Type object for interface requests."""

  def Convert(self, value):
    if value is None:
      return reflection.InterfaceRequest(mojo_system.Handle())
    if not isinstance(value, reflection.InterfaceRequest):
      raise TypeError('%r is not an interface request' % value)
    return value

  def FromHandle(self, handle):
    return reflection.InterfaceRequest(handle)

  def ToHandle(self, value):
    return value.PassMessagePipe()


class InterfaceType(BaseHandleType):
  """Type object for interfaces."""

  def __init__(self, interface_getter, nullable=False):
    # handle (4 bytes) + version (4 bytes)
    BaseHandleType.__init__(self, nullable, 'iI')
    self._interface_getter = interface_getter
    self._interface = None

  def Convert(self, value):
    if value is None or isinstance(value, self.interface):
      return value
    raise TypeError('%r is not an instance of ' % self.interface)

  @property
  def interface(self):
    if not self._interface:
      self._interface = self._interface_getter()
    return self._interface

  def Serialize(self, value, data_offset, data, handle_offset):
    (encoded_handle, handles) = super(InterfaceType, self).Serialize(
        value, data_offset, data, handle_offset)
    if encoded_handle == -1:
      version = 0
    else:
      version = self.interface.manager.version
      if value and isinstance(value, reflection.InterfaceProxy):
        version = value.manager.version
    return ((encoded_handle, version), handles)

  def Deserialize(self, value, context):
    proxy = super(InterfaceType, self).Deserialize(value[0], context)
    if proxy:
      proxy.manager.version = value[1]
    return proxy

  def FromHandle(self, handle):
    if handle.IsValid():
      return self.interface.manager.Proxy(handle)
    return None

  def ToHandle(self, value):
    if not value:
      return mojo_system.Handle()
    if isinstance(value, reflection.InterfaceProxy):
      return value.manager.PassMessagePipe()
    pipe = mojo_system.MessagePipe()
    self.interface.manager.Bind(value, pipe.handle0)
    return pipe.handle1


class BaseArrayType(PointerType):
  """Abstract Type object for arrays."""

  def __init__(self, nullable=False, length=0):
    PointerType.__init__(self, nullable)
    self.length = length

  def SerializePointer(self, value, data_offset, data, handle_offset):
    if self.length != 0 and len(value) != self.length:
      raise serialization.SerializationException('Incorrect array size')
    return self.SerializeArray(value, data_offset, data, handle_offset)

  def SerializeArray(self, value, data_offset, data, handle_offset):
    """Serialize the not null array."""
    raise NotImplementedError()

  def DeserializePointer(self, size, nb_elements, context):
    if self.length != 0 and nb_elements != self.length:
      raise serialization.DeserializationException('Incorrect array size')
    if (size <
        serialization.HEADER_STRUCT.size + self.SizeForLength(nb_elements)):
      raise serialization.DeserializationException('Incorrect array size')
    return self.DeserializeArray(size, nb_elements, context)

  def DeserializeArray(self, size, nb_elements, context):
    raise NotImplementedError()

  def SizeForLength(self, nb_elements):
    raise NotImplementedError()


class BooleanArrayType(BaseArrayType):

  def __init__(self, nullable=False, length=0):
    BaseArrayType.__init__(self, nullable, length)
    self._array_type = NativeArrayType('B', nullable)

  def Convert(self, value):
    if value is None:
      return value
    return [TYPE_BOOL.Convert(x) for x in value]

  def SerializeArray(self, value, data_offset, data, handle_offset):
    groups = [value[i:i+8] for i in range(0, len(value), 8)]
    converted = array.array('B', [_ConvertBooleansToByte(x) for x in groups])
    return _SerializeNativeArray(converted, data_offset, data, len(value))

  def DeserializeArray(self, size, nb_elements, context):
    converted = self._array_type.DeserializeArray(size, nb_elements, context)
    elements = list(itertools.islice(
        itertools.chain.from_iterable(
            [_ConvertByteToBooleans(x, 8) for x in converted]),
        0,
        nb_elements))
    return elements

  def SizeForLength(self, nb_elements):
    return (nb_elements + 7) // 8


class GenericArrayType(BaseArrayType):
  """Type object for arrays of pointers."""

  def __init__(self, sub_type, nullable=False, length=0):
    BaseArrayType.__init__(self, nullable, length)
    assert isinstance(sub_type, SerializableType)
    self.sub_type = sub_type

  def Convert(self, value):
    if value is None:
      return value
    return [self.sub_type.Convert(x) for x in value]

  def SerializeArray(self, value, data_offset, data, handle_offset):
    size = (serialization.HEADER_STRUCT.size +
            self.sub_type.GetByteSize() * len(value))
    data_end = len(data)
    position = len(data) + serialization.HEADER_STRUCT.size
    data.extend(bytearray(size +
                          serialization.NeededPaddingForAlignment(size)))
    returned_handles = []
    to_pack = []
    for item in value:
      (new_data, new_handles) = self.sub_type.Serialize(
          item,
          len(data) - position,
          data,
          handle_offset + len(returned_handles))
      to_pack.extend(serialization.Flatten(new_data))
      returned_handles.extend(new_handles)
      position = position + self.sub_type.GetByteSize()

    serialization.HEADER_STRUCT.pack_into(data, data_end, size, len(value))
    # TODO(azani): Refactor so we don't have to create big formatting strings.
    struct.pack_into(('%s' % self.sub_type.GetTypeCode()) * len(value),
                     data,
                     data_end + serialization.HEADER_STRUCT.size,
                     *to_pack)
    return (data_offset, returned_handles)

  def DeserializeArray(self, size, nb_elements, context):
    # TODO(azani): Refactor so the format string isn't so big.
    values = struct.unpack_from(
        nb_elements * self.sub_type.GetTypeCode(),
        buffer(context.data, serialization.HEADER_STRUCT.size))
    values_per_element = len(self.sub_type.GetTypeCode())
    assert nb_elements * values_per_element == len(values)

    result = []
    sub_context = context.GetSubContext(serialization.HEADER_STRUCT.size)
    for index in xrange(nb_elements):
      if values_per_element == 1:
        value = values[index]
      else:
        value = tuple(values[index * values_per_element :
                             (index + 1) * values_per_element])
      result.append(self.sub_type.Deserialize(
          value,
          sub_context))
      sub_context = sub_context.GetSubContext(self.sub_type.GetByteSize())
    return result

  def SizeForLength(self, nb_elements):
    return nb_elements * self.sub_type.GetByteSize();


class NativeArrayType(BaseArrayType):
  """Type object for arrays of native types."""

  def __init__(self, typecode, nullable=False, length=0):
    BaseArrayType.__init__(self, nullable, length)
    self.array_typecode = typecode
    self.element_size = struct.calcsize('<%s' % self.array_typecode)

  def Convert(self, value):
    if value is None:
      return value
    if (isinstance(value, array.array) and
        value.array_typecode == self.array_typecode):
      return value
    return array.array(self.array_typecode, value)

  def SerializeArray(self, value, data_offset, data, handle_offset):
    return _SerializeNativeArray(value, data_offset, data, len(value))

  def DeserializeArray(self, size, nb_elements, context):
    result = array.array(self.array_typecode)
    result.fromstring(buffer(context.data,
                             serialization.HEADER_STRUCT.size,
                             size - serialization.HEADER_STRUCT.size))
    return result

  def SizeForLength(self, nb_elements):
    return nb_elements * self.element_size


class StructType(PointerType):
  """Type object for structs."""

  def __init__(self, struct_type_getter, nullable=False):
    PointerType.__init__(self)
    self._struct_type_getter = struct_type_getter
    self._struct_type = None
    self.nullable = nullable

  @property
  def struct_type(self):
    if not self._struct_type:
      self._struct_type = self._struct_type_getter()
    return self._struct_type

  def Convert(self, value):
    if value is None or isinstance(value, self.struct_type):
      return value
    raise TypeError('%r is not an instance of %r' % (value, self.struct_type))

  def GetDefaultValue(self, value):
    if value:
      return self.struct_type()
    return None

  def SerializePointer(self, value, data_offset, data, handle_offset):
    (new_data, new_handles) = value.Serialize(handle_offset)
    data.extend(new_data)
    return (data_offset, new_handles)

  def DeserializePointer(self, size, nb_elements, context):
    return self.struct_type.Deserialize(context)


class MapType(SerializableType):
  """Type objects for maps."""

  def __init__(self, key_type, value_type, nullable=False):
    self._key_type = key_type
    self._value_type = value_type
    dictionary = {
      '__metaclass__': reflection.MojoStructType,
      '__module__': __name__,
      'DESCRIPTOR': {
        'fields': [
          SingleFieldGroup('keys', MapType._GetArrayType(key_type), 0, 0),
          SingleFieldGroup('values', MapType._GetArrayType(value_type), 1, 0),
        ],
      }
    }
    self.struct = reflection.MojoStructType('MapStruct', (object,), dictionary)
    self.struct_type = StructType(lambda: self.struct, nullable)
    SerializableType.__init__(self, self.struct_type.typecode)

  def Convert(self, value):
    if value is None:
      return value
    if isinstance(value, dict):
      return dict([(self._key_type.Convert(x), self._value_type.Convert(y)) for
                   x, y in value.iteritems()])
    raise TypeError('%r is not a dictionary.')

  def Serialize(self, value, data_offset, data, handle_offset):
    s = None
    if value is not None:
      keys, values = [], []
      for key, value in value.iteritems():
        keys.append(key)
        values.append(value)
      s = self.struct(keys=keys, values=values)
    return self.struct_type.Serialize(s, data_offset, data, handle_offset)

  def Deserialize(self, value, context):
    s = self.struct_type.Deserialize(value, context)
    if s:
      if len(s.keys) != len(s.values):
        raise serialization.DeserializationException(
            'keys and values do not have the same length.')
      return dict(zip(s.keys, s.values))
    return None

  @staticmethod
  def _GetArrayType(t):
    if t == TYPE_BOOL:
      return BooleanArrayType()
    else:
      return GenericArrayType(t)


TYPE_BOOL = BooleanType('B')

TYPE_INT8 = IntegerType('b')
TYPE_INT16 = IntegerType('h')
TYPE_INT32 = IntegerType('i')
TYPE_INT64 = IntegerType('q')

TYPE_UINT8 = IntegerType('B')
TYPE_UINT16 = IntegerType('H')
TYPE_UINT32 = IntegerType('I')
TYPE_UINT64 = IntegerType('Q')

TYPE_FLOAT = FloatType('f')
TYPE_DOUBLE = FloatType('d')

TYPE_STRING = StringType()
TYPE_NULLABLE_STRING = StringType(True)

TYPE_HANDLE = HandleType()
TYPE_NULLABLE_HANDLE = HandleType(True)

TYPE_INTERFACE_REQUEST = InterfaceRequestType()
TYPE_NULLABLE_INTERFACE_REQUEST = InterfaceRequestType(True)


class FieldDescriptor(object):
  """Describes a field in a generated struct."""

  def __init__(self, name, field_type, index, version, default_value=None):
    self.name = name
    self.field_type = field_type
    self.version = version
    self.index = index
    self._default_value = default_value

  def GetDefaultValue(self):
    return self.field_type.GetDefaultValue(self._default_value)


class FieldGroup(object):
  """
  Describe a list of field in the generated struct that must be
  serialized/deserialized together.
  """
  def __init__(self, descriptors):
    self.descriptors = descriptors

  def GetDescriptors(self):
    return self.descriptors

  def GetTypeCode(self):
    raise NotImplementedError()

  def GetByteSize(self):
    raise NotImplementedError()

  def GetAlignment(self):
    raise NotImplementedError()

  def GetMinVersion(self):
    raise NotImplementedError()

  def GetMaxVersion(self):
    raise NotImplementedError()

  def Serialize(self, obj, data_offset, data, handle_offset):
    raise NotImplementedError()

  def Deserialize(self, value, context):
    raise NotImplementedError()

  def Filter(self, version):
    raise NotImplementedError()


class SingleFieldGroup(FieldGroup, FieldDescriptor):
  """A FieldGroup that contains a single FieldDescriptor."""

  def __init__(self, name, field_type, index, version, default_value=None):
    FieldDescriptor.__init__(
        self, name, field_type, index, version, default_value)
    FieldGroup.__init__(self, [self])

  def GetTypeCode(self):
    return self.field_type.GetTypeCode()

  def GetByteSize(self):
    return self.field_type.GetByteSize()

  def GetAlignment(self):
    return self.field_type.GetAlignment()

  def GetMinVersion(self):
    return self.version

  def GetMaxVersion(self):
    return self.version

  def Serialize(self, obj, data_offset, data, handle_offset):
    value = getattr(obj, self.name)
    return self.field_type.Serialize(value, data_offset, data, handle_offset)

  def Deserialize(self, value, context):
    entity = self.field_type.Deserialize(value, context)
    return { self.name: entity }

  def Filter(self, version):
    return self


class BooleanGroup(FieldGroup):
  """A FieldGroup to pack booleans."""
  def __init__(self, descriptors):
    FieldGroup.__init__(self, descriptors)
    self.min_version = min([descriptor.version  for descriptor in descriptors])
    self.max_version = max([descriptor.version  for descriptor in descriptors])

  def GetTypeCode(self):
    return 'B'

  def GetByteSize(self):
    return 1

  def GetAlignment(self):
    return 1

  def GetMinVersion(self):
    return self.min_version

  def GetMaxVersion(self):
    return self.max_version

  def Serialize(self, obj, data_offset, data, handle_offset):
    value = _ConvertBooleansToByte(
        [getattr(obj, field.name) for field in self.GetDescriptors()])
    return (value, [])

  def Deserialize(self, value, context):
    values =  itertools.izip_longest([x.name for x in self.descriptors],
                                      _ConvertByteToBooleans(value),
                                     fillvalue=False)
    return dict(values)

  def Filter(self, version):
    return BooleanGroup(
        filter(lambda d: d.version <= version, self.descriptors))


def _SerializeNativeArray(value, data_offset, data, length):
  data_size = len(data)
  data.extend(bytearray(serialization.HEADER_STRUCT.size))
  data.extend(buffer(value))
  data_length = len(data) - data_size
  data.extend(bytearray(serialization.NeededPaddingForAlignment(data_length)))
  serialization.HEADER_STRUCT.pack_into(data, data_size, data_length, length)
  return (data_offset, [])


def _ConvertBooleansToByte(booleans):
  """Pack a list of booleans into an integer."""
  return reduce(lambda x, y: x * 2 + y, reversed(booleans), 0)


def _ConvertByteToBooleans(value, min_size=0):
  """Unpack an integer into a list of booleans."""
  res = []
  while value:
    res.append(bool(value&1))
    value = value / 2
  res.extend([False] * (min_size - len(res)))
  return res
