#ifndef SERIALIZE_BIT_SET_HPP_
#define SERIALIZE_BIT_SET_HPP_

#include <Serialize/Base.hpp>
#include <Serialize/OrderedContainers.hpp>
#include <bitset>

template<size_t N>
struct SerialCodec<std::bitset<N>>
{
    static void encode(std::vector<uint8_t> &outBytes, const std::bitset<N> &bitset)
    {
        std::array<uint8_t, (N + 7) / 8> encodedSet = {};

        for (size_t i = 0; i < N; i++)
        {
            if (bitset.test(i))
            {
                size_t byteOffset = i / 8;
                size_t bitOffset = i % 8;

                encodedSet[byteOffset] |= 1 << bitOffset;
            }
        }

        serializeInto(outBytes, encodedSet);
    }

    static size_t decode(const uint8_t *data, size_t size, std::bitset<N> &bitset)
    {
        bitset.reset();

        std::array<uint8_t, (N + 7) / 8> encodedSet;
        size_t result = deserialize(data, size, encodedSet);

        for (size_t i = 0; i < N; i++)
        {
            size_t byteOffset = i / 8;
            size_t bitOffset = i % 8;

            if (encodedSet[byteOffset] & (1 << bitOffset))
            {
                bitset.set(i);
            }
        }

        return result;
    }
};

#endif