import cbor2
from . import bindings


def encode_UUID(encoder, value):
    encoder.encode_semantic(37, value.bytes)


def encode_URL(encoder, value):
    encoder.encode_semantic(32, value.bytes)


def decode_UUID(item, immutable):
    return bindings.UUID(bytes=item)


def decode_URL(item, immutable):
    return bindings.URL(item)


decoders = {
    37: decode_UUID,
    32: decode_URL,
}

encoders = {
    bindings.UUID: encode_UUID,
    bindings.URL: encode_URL,
}


def dumps(obj):
    return cbor2.dumps(obj, encoders=encoders)


def loads(payload):
    return cbor2.loads(payload, semantic_decoders=decoders)


def cleanup(obj):
    """
    recursive walk a object to search for un-wanted CBOR tags.
    Transform this tag in string format, this can be UUID, URL..
    Should be Ok, with list, dicts..
    Warning: This operate in-place changes.
    Warning: This won't work for tags in dict keys.
    """
    if isinstance(obj, list):
        for i in range(0, len(obj)):
            obj[i] = cleanup(obj[i])
        return obj

    if isinstance(obj, dict):
        for k in obj.keys():
            obj.update({k: cleanup(obj[k])})
        return obj

    if type(obj) in bindings.classes:
        return str(obj)
    else:
        return obj
