#ifndef SERIALIZE_MAPS_HPP_
#define SERIALIZE_MAPS_HPP_

#include <Serialize/Base.hpp>
#include <map>
#include <unordered_map>

template<typename TKey, typename TValue>
struct SerialCodec<std::map<TKey, TValue>>
{
    static void encode(std::vector<uint8_t> &outBytes, const std::map<TKey, TValue> &map)
    {
        serializeInto<uint32_t>(outBytes, map.size());

        for (const auto& [ key, value ] : map)
        {
            serializeInto(outBytes, key, value);
        }
    }

    static size_t decode(const uint8_t *data, size_t size, std::map<TKey, TValue> &map)
    {
        size_t sizeDecoded = 0;

        uint32_t count = 0;
        sizeDecoded += deserialize(data, size, count);

        while (count--)
        {
            TKey key{};
            TValue value{};

            sizeDecoded += deserialize(data + sizeDecoded, size - sizeDecoded, key, value);

            map[key] = value;
        }

        return sizeDecoded;
    }
};

template<typename TKey, typename TValue>
struct SerialCodec<std::unordered_map<TKey, TValue>>
{
    static void encode(std::vector<uint8_t> &outBytes, const std::unordered_map<TKey, TValue> &umap)
    {
        serializeInto<uint32_t>(outBytes, umap.size());

        for (const auto& [ key, value ] : umap)
        {
            serializeInto(outBytes, key, value);
        }
    }

    static size_t decode(const uint8_t *data, size_t size, std::unordered_map<TKey, TValue> &umap)
    {
        size_t sizeDecoded = 0;

        uint32_t count = 0;
        sizeDecoded += deserialize(data, size, count);

        while (count--)
        {
            TKey key{};
            TValue value{};

            sizeDecoded += deserialize(data + sizeDecoded, size - sizeDecoded, key, value);

            umap[key] = value;
        }

        return sizeDecoded;
    }
};

#endif