# Copyright DataStax, 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.

import datetime
import base64
import uuid
import re
import json
from decimal import Decimal
from collections import OrderedDict
import logging
import itertools
from functools import partial

import ipaddress


from cassandra.cqltypes import cql_types_from_string
from cassandra.metadata import UserType
from cassandra.util import Polygon, Point, LineString, Duration
from cassandra.datastax.graph.types import Vertex, VertexProperty, Edge, Path, T

__all__ = ['GraphSON1Serializer', 'GraphSON1Deserializer', 'GraphSON1TypeDeserializer',
           'GraphSON2Serializer', 'GraphSON2Deserializer', 'GraphSON2Reader',
           'GraphSON3Serializer', 'GraphSON3Deserializer', 'GraphSON3Reader',
           'to_bigint', 'to_int', 'to_double', 'to_float', 'to_smallint',
           'BooleanTypeIO', 'Int16TypeIO', 'Int32TypeIO', 'DoubleTypeIO',
           'FloatTypeIO', 'UUIDTypeIO', 'BigDecimalTypeIO', 'DurationTypeIO', 'InetTypeIO',
           'InstantTypeIO', 'LocalDateTypeIO', 'LocalTimeTypeIO', 'Int64TypeIO', 'BigIntegerTypeIO',
           'LocalDateTypeIO', 'PolygonTypeIO', 'PointTypeIO', 'LineStringTypeIO', 'BlobTypeIO',
           'GraphSON3Serializer', 'GraphSON3Deserializer', 'UserTypeIO', 'TypeWrapperTypeIO']

"""
Supported types:

DSE Graph      GraphSON 2.0     GraphSON 3.0   |  Python Driver
------------ | -------------- | -------------- | ------------
text         | string         | string         | str
boolean      |                |                | bool
bigint       | g:Int64        | g:Int64        | long
int          | g:Int32        | g:Int32        | int
double       | g:Double       | g:Double       | float
float        | g:Float        | g:Float        | float
uuid         | g:UUID         | g:UUID         | UUID
bigdecimal   | gx:BigDecimal  | gx:BigDecimal  | Decimal
duration     | gx:Duration    | N/A            | timedelta              (Classic graph only)
DSE Duration | N/A            | dse:Duration   | Duration               (Core graph only)
inet         | gx:InetAddress | gx:InetAddress | str (unicode), IPV4Address/IPV6Address (PY3)
timestamp    | gx:Instant     | gx:Instant     | datetime.datetime
date         | gx:LocalDate   | gx:LocalDate   | datetime.date
time         | gx:LocalTime   | gx:LocalTime   | datetime.time
smallint     | gx:Int16       | gx:Int16       | int
varint       | gx:BigInteger  | gx:BigInteger  | long
date         | gx:LocalDate   | gx:LocalDate   | Date
polygon      | dse:Polygon    | dse:Polygon    | Polygon
point        | dse:Point      | dse:Point      | Point
linestring   | dse:Linestring | dse:LineString | LineString
blob         | dse:Blob       | dse:Blob       | bytearray, buffer (PY2), memoryview (PY3), bytes (PY3)
blob         | gx:ByteBuffer  | gx:ByteBuffer  | bytearray, buffer (PY2), memoryview (PY3), bytes (PY3)
list         | N/A            | g:List         | list                   (Core graph only)
map          | N/A            | g:Map          | dict                   (Core graph only)
set          | N/A            | g:Set          | set or list            (Core graph only)
                                                 Can return a list due to numerical values returned by Java
tuple        | N/A            | dse:Tuple      | tuple                  (Core graph only)
udt          | N/A            | dse:UDT        | class or namedtuple    (Core graph only)
"""

MAX_INT32 = 2 ** 32 - 1
MIN_INT32 = -2 ** 31

log = logging.getLogger(__name__)


class _GraphSONTypeType(type):
    """GraphSONType metaclass, required to create a class property."""

    @property
    def graphson_type(cls):
        return "{0}:{1}".format(cls.prefix, cls.graphson_base_type)


class GraphSONTypeIO(object, metaclass=_GraphSONTypeType):
    """Represent a serializable GraphSON type"""

    prefix = 'g'
    graphson_base_type = None
    cql_type = None

    @classmethod
    def definition(cls, value, writer=None):
        return {'cqlType': cls.cql_type}

    @classmethod
    def serialize(cls, value, writer=None):
        return str(value)

    @classmethod
    def deserialize(cls, value, reader=None):
        return value

    @classmethod
    def get_specialized_serializer(cls, value):
        return cls


class TextTypeIO(GraphSONTypeIO):
    cql_type = 'text'


class BooleanTypeIO(GraphSONTypeIO):
    graphson_base_type = None
    cql_type = 'boolean'

    @classmethod
    def serialize(cls, value, writer=None):
        return bool(value)


class IntegerTypeIO(GraphSONTypeIO):

    @classmethod
    def serialize(cls, value, writer=None):
        return value

    @classmethod
    def get_specialized_serializer(cls, value):
        if type(value) is int and (value > MAX_INT32 or value < MIN_INT32):
            return Int64TypeIO

        return Int32TypeIO


class Int16TypeIO(IntegerTypeIO):
    prefix = 'gx'
    graphson_base_type = 'Int16'
    cql_type = 'smallint'


class Int32TypeIO(IntegerTypeIO):
    graphson_base_type = 'Int32'
    cql_type = 'int'


class Int64TypeIO(IntegerTypeIO):
    graphson_base_type = 'Int64'
    cql_type = 'bigint'

    @classmethod
    def deserialize(cls, value, reader=None):
        return value


class FloatTypeIO(GraphSONTypeIO):
    graphson_base_type = 'Float'
    cql_type = 'float'

    @classmethod
    def serialize(cls, value, writer=None):
        return value

    @classmethod
    def deserialize(cls, value, reader=None):
        return float(value)


class DoubleTypeIO(FloatTypeIO):
    graphson_base_type = 'Double'
    cql_type = 'double'


class BigIntegerTypeIO(IntegerTypeIO):
    prefix = 'gx'
    graphson_base_type = 'BigInteger'


class LocalDateTypeIO(GraphSONTypeIO):
    FORMAT = '%Y-%m-%d'

    prefix = 'gx'
    graphson_base_type = 'LocalDate'
    cql_type = 'date'

    @classmethod
    def serialize(cls, value, writer=None):
        return value.isoformat()

    @classmethod
    def deserialize(cls, value, reader=None):
        try:
            return datetime.datetime.strptime(value, cls.FORMAT).date()
        except ValueError:
            # negative date
            return value


class InstantTypeIO(GraphSONTypeIO):
    prefix = 'gx'
    graphson_base_type = 'Instant'
    cql_type = 'timestamp'

    @classmethod
    def serialize(cls, value, writer=None):
        if isinstance(value, datetime.datetime):
            value = datetime.datetime(*value.utctimetuple()[:6]).replace(microsecond=value.microsecond)
        else:
            value = datetime.datetime.combine(value, datetime.datetime.min.time())

        return "{0}Z".format(value.isoformat())

    @classmethod
    def deserialize(cls, value, reader=None):
        try:
            d = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%fZ')
        except ValueError:
            d = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%SZ')
        return d


class LocalTimeTypeIO(GraphSONTypeIO):
    FORMATS = [
        '%H:%M',
        '%H:%M:%S',
        '%H:%M:%S.%f'
    ]

    prefix = 'gx'
    graphson_base_type = 'LocalTime'
    cql_type = 'time'

    @classmethod
    def serialize(cls, value, writer=None):
        return value.strftime(cls.FORMATS[2])

    @classmethod
    def deserialize(cls, value, reader=None):
        dt = None
        for f in cls.FORMATS:
            try:
                dt = datetime.datetime.strptime(value, f)
                break
            except ValueError:
                continue

        if dt is None:
            raise ValueError('Unable to decode LocalTime: {0}'.format(value))

        return dt.time()


class BlobTypeIO(GraphSONTypeIO):
    prefix = 'dse'
    graphson_base_type = 'Blob'
    cql_type = 'blob'

    @classmethod
    def serialize(cls, value, writer=None):
        value = base64.b64encode(value)
        value = value.decode('utf-8')
        return value

    @classmethod
    def deserialize(cls, value, reader=None):
        return bytearray(base64.b64decode(value))


class ByteBufferTypeIO(BlobTypeIO):
    prefix = 'gx'
    graphson_base_type = 'ByteBuffer'


class UUIDTypeIO(GraphSONTypeIO):
    graphson_base_type = 'UUID'
    cql_type = 'uuid'

    @classmethod
    def deserialize(cls, value, reader=None):
        return uuid.UUID(value)


class BigDecimalTypeIO(GraphSONTypeIO):
    prefix = 'gx'
    graphson_base_type = 'BigDecimal'
    cql_type = 'bigdecimal'

    @classmethod
    def deserialize(cls, value, reader=None):
        return Decimal(value)


class DurationTypeIO(GraphSONTypeIO):
    prefix = 'gx'
    graphson_base_type = 'Duration'
    cql_type = 'duration'

    _duration_regex = re.compile(r"""
        ^P((?P<days>\d+)D)?
        T((?P<hours>\d+)H)?
        ((?P<minutes>\d+)M)?
        ((?P<seconds>[0-9.]+)S)?$
    """, re.VERBOSE)
    _duration_format = "P{days}DT{hours}H{minutes}M{seconds}S"

    _seconds_in_minute = 60
    _seconds_in_hour = 60 * _seconds_in_minute
    _seconds_in_day = 24 * _seconds_in_hour

    @classmethod
    def serialize(cls, value, writer=None):
        total_seconds = int(value.total_seconds())
        days, total_seconds = divmod(total_seconds, cls._seconds_in_day)
        hours, total_seconds = divmod(total_seconds, cls._seconds_in_hour)
        minutes, total_seconds = divmod(total_seconds, cls._seconds_in_minute)
        total_seconds += value.microseconds / 1e6

        return cls._duration_format.format(
            days=int(days), hours=int(hours), minutes=int(minutes), seconds=total_seconds
        )

    @classmethod
    def deserialize(cls, value, reader=None):
        duration = cls._duration_regex.match(value)
        if duration is None:
            raise ValueError('Invalid duration: {0}'.format(value))

        duration = {k: float(v) if v is not None else 0
                    for k, v in duration.groupdict().items()}
        return datetime.timedelta(days=duration['days'], hours=duration['hours'],
                                  minutes=duration['minutes'], seconds=duration['seconds'])


class DseDurationTypeIO(GraphSONTypeIO):
    prefix = 'dse'
    graphson_base_type = 'Duration'
    cql_type = 'duration'

    @classmethod
    def serialize(cls, value, writer=None):
        return {
            'months': value.months,
            'days': value.days,
            'nanos': value.nanoseconds
        }

    @classmethod
    def deserialize(cls, value, reader=None):
        return Duration(
            reader.deserialize(value['months']),
            reader.deserialize(value['days']),
            reader.deserialize(value['nanos'])
        )


class TypeWrapperTypeIO(GraphSONTypeIO):

    @classmethod
    def definition(cls, value, writer=None):
        return {'cqlType': value.type_io.cql_type}

    @classmethod
    def serialize(cls, value, writer=None):
        return value.type_io.serialize(value.value)

    @classmethod
    def deserialize(cls, value, reader=None):
        return value.type_io.deserialize(value.value)


class PointTypeIO(GraphSONTypeIO):
    prefix = 'dse'
    graphson_base_type = 'Point'
    cql_type = "org.apache.cassandra.db.marshal.PointType"

    @classmethod
    def deserialize(cls, value, reader=None):
        return Point.from_wkt(value)


class LineStringTypeIO(GraphSONTypeIO):
    prefix = 'dse'
    graphson_base_type = 'LineString'
    cql_type = "org.apache.cassandra.db.marshal.LineStringType"

    @classmethod
    def deserialize(cls, value, reader=None):
        return LineString.from_wkt(value)


class PolygonTypeIO(GraphSONTypeIO):
    prefix = 'dse'
    graphson_base_type = 'Polygon'
    cql_type = "org.apache.cassandra.db.marshal.PolygonType"

    @classmethod
    def deserialize(cls, value, reader=None):
        return Polygon.from_wkt(value)


class InetTypeIO(GraphSONTypeIO):
    prefix = 'gx'
    graphson_base_type = 'InetAddress'
    cql_type = 'inet'


class VertexTypeIO(GraphSONTypeIO):
    graphson_base_type = 'Vertex'

    @classmethod
    def deserialize(cls, value, reader=None):
        vertex = Vertex(id=reader.deserialize(value["id"]),
                        label=value["label"] if "label" in value else "vertex",
                        type='vertex',
                        properties={})
        # avoid the properties processing in Vertex.__init__
        vertex.properties = reader.deserialize(value.get('properties', {}))
        return vertex


class VertexPropertyTypeIO(GraphSONTypeIO):
    graphson_base_type = 'VertexProperty'

    @classmethod
    def deserialize(cls, value, reader=None):
        return VertexProperty(label=value['label'],
                              value=reader.deserialize(value["value"]),
                              properties=reader.deserialize(value.get('properties', {})))


class EdgeTypeIO(GraphSONTypeIO):
    graphson_base_type = 'Edge'

    @classmethod
    def deserialize(cls, value, reader=None):
        in_vertex = Vertex(id=reader.deserialize(value["inV"]),
                           label=value['inVLabel'],
                           type='vertex',
                           properties={})
        out_vertex = Vertex(id=reader.deserialize(value["outV"]),
                            label=value['outVLabel'],
                            type='vertex',
                            properties={})
        return Edge(
            id=reader.deserialize(value["id"]),
            label=value["label"] if "label" in value else "vertex",
            type='edge',
            properties=reader.deserialize(value.get("properties", {})),
            inV=in_vertex,
            inVLabel=value['inVLabel'],
            outV=out_vertex,
            outVLabel=value['outVLabel']
        )


class PropertyTypeIO(GraphSONTypeIO):
    graphson_base_type = 'Property'

    @classmethod
    def deserialize(cls, value, reader=None):
        return {value["key"]: reader.deserialize(value["value"])}


class PathTypeIO(GraphSONTypeIO):
    graphson_base_type = 'Path'

    @classmethod
    def deserialize(cls, value, reader=None):
        labels = [set(label) for label in reader.deserialize(value['labels'])]
        objects = [obj for obj in reader.deserialize(value['objects'])]
        p = Path(labels, [])
        p.objects = objects  # avoid the object processing in Path.__init__
        return p


class TraversalMetricsTypeIO(GraphSONTypeIO):
    graphson_base_type = 'TraversalMetrics'

    @classmethod
    def deserialize(cls, value, reader=None):
        return reader.deserialize(value)


class MetricsTypeIO(GraphSONTypeIO):
    graphson_base_type = 'Metrics'

    @classmethod
    def deserialize(cls, value, reader=None):
        return reader.deserialize(value)


class JsonMapTypeIO(GraphSONTypeIO):
    """In GraphSON2, dict are simply serialized as json map"""

    @classmethod
    def serialize(cls, value, writer=None):
        out = {}
        for k, v in value.items():
            out[k] = writer.serialize(v, writer)

        return out


class MapTypeIO(GraphSONTypeIO):
    """In GraphSON3, dict has its own type"""

    graphson_base_type = 'Map'
    cql_type = 'map'

    @classmethod
    def definition(cls, value, writer=None):
        out = OrderedDict([('cqlType', cls.cql_type)])
        out['definition'] = []
        for k, v in value.items():
            # we just need the first pair to write the def
            out['definition'].append(writer.definition(k))
            out['definition'].append(writer.definition(v))
            break
        return out

    @classmethod
    def serialize(cls, value, writer=None):
        out = []
        for k, v in value.items():
            out.append(writer.serialize(k, writer))
            out.append(writer.serialize(v, writer))

        return out

    @classmethod
    def deserialize(cls, value, reader=None):
        out = {}
        a, b = itertools.tee(value)
        for key, val in zip(
            itertools.islice(a, 0, None, 2),
            itertools.islice(b, 1, None, 2)
        ):
            out[reader.deserialize(key)] = reader.deserialize(val)
        return out


class ListTypeIO(GraphSONTypeIO):
    """In GraphSON3, list has its own type"""

    graphson_base_type = 'List'
    cql_type = 'list'

    @classmethod
    def definition(cls, value, writer=None):
        out = OrderedDict([('cqlType', cls.cql_type)])
        out['definition'] = []
        if value:
            out['definition'].append(writer.definition(value[0]))
        return out

    @classmethod
    def serialize(cls, value, writer=None):
        return [writer.serialize(v, writer) for v in value]

    @classmethod
    def deserialize(cls, value, reader=None):
        return [reader.deserialize(obj) for obj in value]


class SetTypeIO(GraphSONTypeIO):
    """In GraphSON3, set has its own type"""

    graphson_base_type = 'Set'
    cql_type = 'set'

    @classmethod
    def definition(cls, value, writer=None):
        out = OrderedDict([('cqlType', cls.cql_type)])
        out['definition'] = []
        for v in value:
            # we only take into account the first value for the definition
            out['definition'].append(writer.definition(v))
            break
        return out

    @classmethod
    def serialize(cls, value, writer=None):
        return [writer.serialize(v, writer) for v in value]

    @classmethod
    def deserialize(cls, value, reader=None):
        lst = [reader.deserialize(obj) for obj in value]

        s = set(lst)
        if len(s) != len(lst):
            log.warning("Coercing g:Set to list due to numerical values returned by Java. "
                        "See TINKERPOP-1844 for details.")
            return lst

        return s


class BulkSetTypeIO(GraphSONTypeIO):
    graphson_base_type = "BulkSet"

    @classmethod
    def deserialize(cls, value, reader=None):
        out = []

        a, b = itertools.tee(value)
        for val, bulk in zip(
            itertools.islice(a, 0, None, 2),
            itertools.islice(b, 1, None, 2)
        ):
            val = reader.deserialize(val)
            bulk = reader.deserialize(bulk)
            for n in range(bulk):
                out.append(val)

        return out


class TupleTypeIO(GraphSONTypeIO):
    prefix = 'dse'
    graphson_base_type = 'Tuple'
    cql_type = 'tuple'

    @classmethod
    def definition(cls, value, writer=None):
        out = OrderedDict()
        out['cqlType'] = cls.cql_type
        serializers = [writer.get_serializer(s) for s in value]
        out['definition'] = [s.definition(v, writer) for v, s in zip(value, serializers)]
        return out

    @classmethod
    def serialize(cls, value, writer=None):
        out = cls.definition(value, writer)
        out['value'] = [writer.serialize(v, writer) for v in value]
        return out

    @classmethod
    def deserialize(cls, value, reader=None):
        return tuple(reader.deserialize(obj) for obj in value['value'])


class UserTypeIO(GraphSONTypeIO):
    prefix = 'dse'
    graphson_base_type = 'UDT'
    cql_type = 'udt'

    FROZEN_REMOVAL_REGEX = re.compile(r'frozen<"*([^"]+)"*>')

    @classmethod
    def cql_types_from_string(cls, typ):
        # sanitizing: remove frozen references and double quotes...
        return cql_types_from_string(
            re.sub(cls.FROZEN_REMOVAL_REGEX, r'\1', typ)
        )

    @classmethod
    def get_udt_definition(cls, value, writer):
        user_type_name = writer.user_types[type(value)]
        keyspace = writer.context['graph_name']
        return writer.context['cluster'].metadata.keyspaces[keyspace].user_types[user_type_name]

    @classmethod
    def is_collection(cls, typ):
        return typ in ['list', 'tuple', 'map', 'set']

    @classmethod
    def is_udt(cls, typ, writer):
        keyspace = writer.context['graph_name']
        if keyspace in writer.context['cluster'].metadata.keyspaces:
            return typ in writer.context['cluster'].metadata.keyspaces[keyspace].user_types
        return False

    @classmethod
    def field_definition(cls, types, writer, name=None):
        """
        Build the udt field definition. This is required when we have a complex udt type.
        """
        index = -1
        out = [OrderedDict() if name is None else OrderedDict([('fieldName', name)])]

        while types:
            index += 1
            typ = types.pop(0)
            if index > 0:
                out.append(OrderedDict())

            if cls.is_udt(typ, writer):
                keyspace = writer.context['graph_name']
                udt = writer.context['cluster'].metadata.keyspaces[keyspace].user_types[typ]
                out[index].update(cls.definition(udt, writer))
            elif cls.is_collection(typ):
                out[index]['cqlType'] = typ
                definition = cls.field_definition(types, writer)
                out[index]['definition'] = definition if isinstance(definition, list) else [definition]
            else:
                out[index]['cqlType'] = typ

        return out if len(out) > 1 else out[0]

    @classmethod
    def definition(cls, value, writer=None):
        udt = value if isinstance(value, UserType) else cls.get_udt_definition(value, writer)
        return OrderedDict([
            ('cqlType', cls.cql_type),
            ('keyspace', udt.keyspace),
            ('name', udt.name),
            ('definition', [
                cls.field_definition(cls.cql_types_from_string(typ), writer, name=name)
                for name, typ in zip(udt.field_names, udt.field_types)])
        ])

    @classmethod
    def serialize(cls, value, writer=None):
        udt = cls.get_udt_definition(value, writer)
        out = cls.definition(value, writer)
        out['value'] = []
        for name, typ in zip(udt.field_names, udt.field_types):
            out['value'].append(writer.serialize(getattr(value, name), writer))
        return out

    @classmethod
    def deserialize(cls, value, reader=None):
        udt_class = reader.context['cluster']._user_types[value['keyspace']][value['name']]
        kwargs = zip(
            list(map(lambda v: v['fieldName'], value['definition'])),
            [reader.deserialize(v) for v in value['value']]
        )
        return udt_class(**dict(kwargs))


class TTypeIO(GraphSONTypeIO):
    prefix = 'g'
    graphson_base_type = 'T'

    @classmethod
    def deserialize(cls, value, reader=None):
        return T.name_to_value[value]


class _BaseGraphSONSerializer(object):

    _serializers = OrderedDict()

    @classmethod
    def register(cls, type, serializer):
        cls._serializers[type] = serializer

    @classmethod
    def get_type_definitions(cls):
        return cls._serializers.copy()

    @classmethod
    def get_serializer(cls, value):
        """
        Get the serializer for a python object.

        :param value: The python object.
        """

        # The serializer matching logic is as follow:
        # 1. Try to find the python type by direct access.
        # 2. Try to find the first serializer by class inheritance.
        # 3. If no serializer found, return the raw value.

        # Note that when trying to find the serializer by class inheritance,
        # the order that serializers are registered is important. The use of
        # an OrderedDict is to avoid the difference between executions.
        serializer = None
        try:
            serializer = cls._serializers[type(value)]
        except KeyError:
            for key, serializer_ in cls._serializers.items():
                if isinstance(value, key):
                    serializer = serializer_
                    break

        if serializer:
            # A serializer can have specialized serializers (e.g for Int32 and Int64, so value dependant)
            serializer = serializer.get_specialized_serializer(value)

        return serializer

    @classmethod
    def serialize(cls, value, writer=None):
        """
        Serialize a python object to GraphSON.

        e.g 'P42DT10H5M37S'
        e.g. {'key': value}

        :param value: The python object to serialize.
        :param writer: A graphson serializer for recursive types (Optional)
        """
        serializer = cls.get_serializer(value)
        if serializer:
            return serializer.serialize(value, writer or cls)

        return value


class GraphSON1Serializer(_BaseGraphSONSerializer):
    """
    Serialize python objects to graphson types.
    """

    # When we fall back to a superclass's serializer, we iterate over this map.
    # We want that iteration order to be consistent, so we use an OrderedDict,
    # not a dict.
    _serializers = OrderedDict([
        (str, TextTypeIO),
        (bool, BooleanTypeIO),
        (bytearray, ByteBufferTypeIO),
        (Decimal, BigDecimalTypeIO),
        (datetime.date, LocalDateTypeIO),
        (datetime.time, LocalTimeTypeIO),
        (datetime.timedelta, DurationTypeIO),
        (datetime.datetime, InstantTypeIO),
        (uuid.UUID, UUIDTypeIO),
        (Polygon, PolygonTypeIO),
        (Point, PointTypeIO),
        (LineString, LineStringTypeIO),
        (dict, JsonMapTypeIO),
        (float, FloatTypeIO)
    ])


GraphSON1Serializer.register(ipaddress.IPv4Address, InetTypeIO)
GraphSON1Serializer.register(ipaddress.IPv6Address, InetTypeIO)
GraphSON1Serializer.register(memoryview, ByteBufferTypeIO)
GraphSON1Serializer.register(bytes, ByteBufferTypeIO)


class _BaseGraphSONDeserializer(object):

    _deserializers = {}

    @classmethod
    def get_type_definitions(cls):
        return cls._deserializers.copy()

    @classmethod
    def register(cls, graphson_type, serializer):
        cls._deserializers[graphson_type] = serializer

    @classmethod
    def get_deserializer(cls, graphson_type):
        try:
            return cls._deserializers[graphson_type]
        except KeyError:
            raise ValueError('Invalid `graphson_type` specified: {}'.format(graphson_type))

    @classmethod
    def deserialize(cls, graphson_type, value):
        """
        Deserialize a `graphson_type` value to a python object.

        :param graphson_base_type: The graphson graphson_type. e.g. 'gx:Instant'
        :param value: The graphson value to deserialize.
        """
        return cls.get_deserializer(graphson_type).deserialize(value)


class GraphSON1Deserializer(_BaseGraphSONDeserializer):
    """
    Deserialize graphson1 types to python objects.
    """
    _TYPES = [UUIDTypeIO, BigDecimalTypeIO, InstantTypeIO, BlobTypeIO, ByteBufferTypeIO,
              PointTypeIO, LineStringTypeIO, PolygonTypeIO, LocalDateTypeIO,
              LocalTimeTypeIO, DurationTypeIO, InetTypeIO]

    _deserializers = {
        t.graphson_type: t
        for t in _TYPES
    }

    @classmethod
    def deserialize_date(cls, value):
        return cls._deserializers[LocalDateTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_time(cls, value):
        return cls._deserializers[LocalTimeTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_timestamp(cls, value):
        return cls._deserializers[InstantTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_duration(cls, value):
        return cls._deserializers[DurationTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_int(cls, value):
        return int(value)

    deserialize_smallint = deserialize_int

    deserialize_varint = deserialize_int

    @classmethod
    def deserialize_bigint(cls, value):
        return cls.deserialize_int(value)

    @classmethod
    def deserialize_double(cls, value):
        return float(value)

    deserialize_float = deserialize_double

    @classmethod
    def deserialize_uuid(cls, value):
        return cls._deserializers[UUIDTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_decimal(cls, value):
        return cls._deserializers[BigDecimalTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_blob(cls, value):
        return cls._deserializers[ByteBufferTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_point(cls, value):
        return cls._deserializers[PointTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_linestring(cls, value):
        return cls._deserializers[LineStringTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_polygon(cls, value):
        return cls._deserializers[PolygonTypeIO.graphson_type].deserialize(value)

    @classmethod
    def deserialize_inet(cls, value):
        return value

    @classmethod
    def deserialize_boolean(cls, value):
        return value


# TODO Remove in the next major
GraphSON1TypeDeserializer = GraphSON1Deserializer
GraphSON1TypeSerializer = GraphSON1Serializer


class GraphSON2Serializer(_BaseGraphSONSerializer):
    TYPE_KEY = "@type"
    VALUE_KEY = "@value"

    _serializers = GraphSON1Serializer.get_type_definitions()

    def serialize(self, value, writer=None):
        """
        Serialize a type to GraphSON2.

        e.g {'@type': 'gx:Duration', '@value': 'P2DT4H'}

        :param value: The python object to serialize.
        """
        serializer = self.get_serializer(value)
        if not serializer:
            raise ValueError("Unable to find a serializer for value of type: ".format(type(value)))

        val = serializer.serialize(value, writer or self)
        if serializer is TypeWrapperTypeIO:
            graphson_base_type = value.type_io.graphson_base_type
            graphson_type = value.type_io.graphson_type
        else:
            graphson_base_type = serializer.graphson_base_type
            graphson_type = serializer.graphson_type

        if graphson_base_type is None:
            out = val
        else:
            out = {self.TYPE_KEY: graphson_type}
            if val is not None:
                out[self.VALUE_KEY] = val

        return out


GraphSON2Serializer.register(int, IntegerTypeIO)


class GraphSON2Deserializer(_BaseGraphSONDeserializer):

    _TYPES = GraphSON1Deserializer._TYPES + [
        Int16TypeIO, Int32TypeIO, Int64TypeIO, DoubleTypeIO, FloatTypeIO,
        BigIntegerTypeIO, VertexTypeIO, VertexPropertyTypeIO, EdgeTypeIO,
        PathTypeIO, PropertyTypeIO, TraversalMetricsTypeIO, MetricsTypeIO]

    _deserializers = {
        t.graphson_type: t
        for t in _TYPES
    }


class GraphSON2Reader(object):
    """
    GraphSON2 Reader that parse json and deserialize to python objects.
    """

    def __init__(self, context, extra_deserializer_map=None):
        """
        :param extra_deserializer_map: map from GraphSON type tag to deserializer instance implementing `deserialize`
        """
        self.context = context
        self.deserializers = GraphSON2Deserializer.get_type_definitions()
        if extra_deserializer_map:
            self.deserializers.update(extra_deserializer_map)

    def read(self, json_data):
        """
        Read and deserialize ``json_data``.
        """
        return self.deserialize(json.loads(json_data))

    def deserialize(self, obj):
        """
        Deserialize GraphSON type-tagged dict values into objects mapped in self.deserializers
        """
        if isinstance(obj, dict):
            try:
                des = self.deserializers[obj[GraphSON2Serializer.TYPE_KEY]]
                return des.deserialize(obj[GraphSON2Serializer.VALUE_KEY], self)
            except KeyError:
                pass
            # list and map are treated as normal json objs (could be isolated deserializers)
            return {self.deserialize(k): self.deserialize(v) for k, v in obj.items()}
        elif isinstance(obj, list):
            return [self.deserialize(o) for o in obj]
        else:
            return obj


class TypeIOWrapper(object):
    """Used to force a graphson type during serialization"""

    type_io = None
    value = None

    def __init__(self, type_io, value):
        self.type_io = type_io
        self.value = value


def _wrap_value(type_io, value):
    return TypeIOWrapper(type_io, value)


to_bigint = partial(_wrap_value, Int64TypeIO)
to_int = partial(_wrap_value, Int32TypeIO)
to_smallint = partial(_wrap_value, Int16TypeIO)
to_double = partial(_wrap_value, DoubleTypeIO)
to_float = partial(_wrap_value, FloatTypeIO)


class GraphSON3Serializer(GraphSON2Serializer):

    _serializers = GraphSON2Serializer.get_type_definitions()

    context = None
    """A dict of the serialization context"""

    def __init__(self, context):
        self.context = context
        self.user_types = None

    def definition(self, value):
        serializer = self.get_serializer(value)
        return serializer.definition(value, self)

    def get_serializer(self, value):
        """Custom get_serializer to support UDT/Tuple"""

        serializer = super(GraphSON3Serializer, self).get_serializer(value)
        is_namedtuple_udt = serializer is TupleTypeIO and hasattr(value, '_fields')
        if not serializer or is_namedtuple_udt:
            # Check if UDT
            if self.user_types is None:
                try:
                    user_types = self.context['cluster']._user_types[self.context['graph_name']]
                    self.user_types = dict(map(reversed, user_types.items()))
                except KeyError:
                    self.user_types = {}

            serializer = UserTypeIO if (is_namedtuple_udt or (type(value) in self.user_types)) else serializer

        return serializer


GraphSON3Serializer.register(dict, MapTypeIO)
GraphSON3Serializer.register(list, ListTypeIO)
GraphSON3Serializer.register(set, SetTypeIO)
GraphSON3Serializer.register(tuple, TupleTypeIO)
GraphSON3Serializer.register(Duration, DseDurationTypeIO)
GraphSON3Serializer.register(TypeIOWrapper, TypeWrapperTypeIO)


class GraphSON3Deserializer(GraphSON2Deserializer):
    _TYPES = GraphSON2Deserializer._TYPES + [MapTypeIO, ListTypeIO,
                                             SetTypeIO, TupleTypeIO,
                                             UserTypeIO, DseDurationTypeIO,
                                             TTypeIO, BulkSetTypeIO]

    _deserializers = {t.graphson_type: t for t in _TYPES}


class GraphSON3Reader(GraphSON2Reader):
    """
    GraphSON3 Reader that parse json and deserialize to python objects.
    """

    def __init__(self, context, extra_deserializer_map=None):
        """
        :param context: A dict of the context, mostly used as context for udt deserialization.
        :param extra_deserializer_map: map from GraphSON type tag to deserializer instance implementing `deserialize`
        """
        self.context = context
        self.deserializers = GraphSON3Deserializer.get_type_definitions()
        if extra_deserializer_map:
            self.deserializers.update(extra_deserializer_map)
