import json

from eth_utils import decode_hex, encode_hex

from ssz.examples.zoo import Animal, Zoo, octopus, zoo
from ssz.hashable_list import HashableList
from ssz.sedes import List
from ssz.tools import DefaultCodec, from_formatted_dict, to_formatted_dict


def test_parsing_and_dumping():
    json_str = json.dumps(to_formatted_dict(zoo))
    read_zoo = from_formatted_dict(json.loads(json_str), Zoo)
    assert read_zoo == zoo


def test_dump_serializble_with_explicit_sedes():
    to_formatted_dict(zoo, Zoo)


def test_not_serializable():
    octopi = (octopus, octopus, octopus)
    sedes = List(Animal, 2 ** 32)
    output = to_formatted_dict(octopi, sedes)

    hashable_octopi = HashableList.from_iterable(octopi, sedes)
    assert hashable_octopi == from_formatted_dict(output, List(Animal, 2 ** 32))


def test_custom_codec():
    class CustomCodec(DefaultCodec):
        @staticmethod
        def format_integer(value, sedes):
            return encode_hex(sedes.serialize(value))

        @staticmethod
        def unformat_integer(value, sedes):
            return sedes.deserialize(decode_hex(value))

    output = to_formatted_dict(zoo, codec=CustomCodec)
    read_zoo = from_formatted_dict(output, Zoo, CustomCodec)
    assert read_zoo == zoo
