# -*- coding: utf-8 -*-

"""
mygeotab.serializers
~~~~~~~~~~~~~~~~~~~~

JSON serialization and deserialization helper objects for the MyGeotab API.
"""

import json
import re

import arrow

from . import dates

use_rapidjson = False
try:
    import rapidjson

    DATETIME_MODE = rapidjson.DM_SHIFT_TO_UTC | rapidjson.DM_ISO8601

    use_rapidjson = True
except ImportError:
    pass

DATETIME_REGEX = re.compile(r"^\d{4}\-\d{2}\-\d{2}")


def json_serialize(obj):
    if use_rapidjson:
        return rapidjson.dumps(obj, default=object_serializer)
    return json.dumps(obj, default=object_serializer, separators=(",", ":"))


def json_deserialize(json_str):
    if use_rapidjson:
        return rapidjson.loads(json_str, datetime_mode=DATETIME_MODE)
    return json.loads(json_str, object_hook=object_deserializer)


def object_serializer(obj):
    """Helper to serialize a field into a compatible MyGeotab object.

    :param obj: The object.
    """
    if hasattr(obj, "isoformat"):
        return dates.format_iso_datetime(obj)
    else:
        # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(obj)


def object_deserializer(obj):
    """Helper to deserialize a raw result dict into a proper dict.

    :param obj: The dict.
    """
    for key, val in obj.items():
        if isinstance(val, str) and DATETIME_REGEX.search(val):
            try:
                obj[key] = dates.localize_datetime(arrow.get(val).datetime)
            except (ValueError, arrow.parser.ParserError):
                obj[key] = val
    return obj
