#include "ByteUtils.h"
#include "BufferBitStream.h"

#include "TestFramework.h"

#include <iostream>

TEST_CASE(TestReadBitStream, "core")
{
    std::vector<std::string> bytes{
        "11101101",
        "01011101",
        "00001001",
        "01111111"};

    BufferBitStream stream;
    for(const auto& byte : bytes)
    {
        stream.writeByte(ByteUtils::getFromString(byte));
    }

    unsigned char buffer{0} ;
    auto valid = stream.readNextNBits(1, buffer);
    //std::cout << "Slice0 is " << ByteUtils::toString(buffer) << std::endl;

    valid = stream.readNextNBits(2, buffer);
    //std::cout << "Slice1 is " << ByteUtils::toString(buffer) << std::endl;

    valid = stream.readNextNBits(5, buffer);
    //std::cout << "Slice2 is " << ByteUtils::toString(buffer) << std::endl;

    valid = stream.readNextNBits(5, buffer);
    //std::cout << "Slice3 is " << ByteUtils::toString(buffer) << std::endl;

    valid = stream.readNextNBits(4, buffer);
    //std::cout << "Slice3 is " << ByteUtils::toString(buffer) << " and int " << static_cast<int>(buffer) << std::endl;

    valid = stream.readNextNBits(3, buffer);
    //std::cout << "Slice3 is " << ByteUtils::toString(buffer) << std::endl;
}

TEST_CASE(TestWritingBitStream, "core")
{
    BufferBitStream stream;

    stream.writeByte(ByteUtils::getFromString("01100000"));

    auto bits0 = ByteUtils::getFromString("00000111");
    stream.writeNBits(bits0, 3);

    stream.writeByte(ByteUtils::getFromString("11110000"));

    auto bits1 = ByteUtils::getFromString("01001101");
    stream.writeNBits(bits1, 7);

    stream.writeByte(ByteUtils::getFromString("11110000"));

    auto bits2 = ByteUtils::getFromString("00000001");
    stream.writeNBits(bits2, 1);

    stream.flushRemainingBits();

    stream.resetOffsets();

    auto byte0 = ByteUtils::toString(*stream.readNextByte());
    auto byte1 = ByteUtils::toString(*stream.readNextByte());
    auto byte2 = ByteUtils::toString(*stream.readNextByte());
    auto byte3 = ByteUtils::toString(*stream.readNextByte());
    auto byte4 = ByteUtils::toString(*stream.readNextByte());

    //std::cout << "Got bytes 0 " << byte0 << std::endl;
    //std::cout << "Got bytes 1 " << byte1 << std::endl;
    //std::cout << "Got bytes 2 " << byte2 << std::endl;
    //std::cout << "Got bytes 3 " << byte3 << std::endl;
    //std::cout << "Got bytes 4 " << byte4 << std::endl;
}
