/** @file hei_bit_string.cpp
 *  @brief BitString and BitStringBuffer class definitions
 */

#include <hei_user_defines.hpp>
#include <util/hei_bit_string.hpp>

#include <algorithm>

namespace libhei
{

//##############################################################################
//                             BitString class
//##############################################################################

// number of bits in a uint64_t
constexpr uint64_t BitString::UINT64_BIT_LEN = sizeof(uint64_t) * 8;
// number of bits in a uint8_t
constexpr uint64_t BitString::UINT8_BIT_LEN = sizeof(uint8_t) * 8;

//------------------------------------------------------------------------------

uint64_t BitString::getFieldRight(uint64_t i_pos, uint64_t i_len) const
{
    HEI_ASSERT(nullptr != getBufAddr());      // must to have a valid address
    HEI_ASSERT(0 < i_len);                    // must have at least one bit
    HEI_ASSERT(i_len <= UINT64_BIT_LEN);      // i_len length must be valid
    HEI_ASSERT(i_pos + i_len <= getBitLen()); // field must be within range

    // Get the relative address of this byte and the relative starting position
    // within the byte.
    uint64_t relPos  = 0;
    uint8_t* relAddr = getRelativePosition(relPos, i_pos);

    // Get the length of the target bit field within this byte and the length of
    // the bit field for any remaining bits.
    uint64_t bf_len     = i_len;
    uint64_t remain_len = 0;
    if (UINT8_BIT_LEN < relPos + i_len)
    {
        // The target bit field crosses a byte boundary. So truncate the bit
        // length for this byte and update the remaining length.
        bf_len     = UINT8_BIT_LEN - relPos;
        remain_len = i_len - bf_len;
    }

    // Get the target bit field within this byte (right justified).
    uint8_t bf = *relAddr;
    bf <<= relPos;                 // Mask off uneeded bits on the left side.
    bf >>= UINT8_BIT_LEN - bf_len; // Right justify the value.

    // Check for any remaining bits after this target byte.
    if (0 != remain_len)
    {
        // Recursively call this function on the remaining bits and push them
        // into the right side of the return value.
        uint64_t val = static_cast<uint64_t>(bf) << remain_len;
        return val | getFieldRight(i_pos + bf_len, remain_len);
    }

    // Nothing more to do. Simply return this bit field.
    return bf;
}

//------------------------------------------------------------------------------

void BitString::setFieldLeft(uint64_t i_pos, uint64_t i_len, uint64_t i_val)
{
    HEI_ASSERT(nullptr != getBufAddr());      // must to have a valid address
    HEI_ASSERT(0 < i_len);                    // must have at least one bit
    HEI_ASSERT(i_len <= UINT64_BIT_LEN);      // i_len length must be valid
    HEI_ASSERT(i_pos + i_len <= getBitLen()); // field must be within range

    // Get the relative address of this byte and the relative starting position
    // within the byte.
    uint64_t relPos  = 0;
    uint8_t* relAddr = getRelativePosition(relPos, i_pos);

    // Get the length of the target bit field within this byte and the length of
    // the bit field for any remaining bits.
    uint64_t bf_len     = i_len;
    uint64_t remain_len = 0;
    if (UINT8_BIT_LEN < relPos + i_len)
    {
        // The target bit field crosses a byte boundary. So truncate the bit
        // length for this byte and update the remaining length.
        bf_len     = UINT8_BIT_LEN - relPos;
        remain_len = i_len - bf_len;
    }

    // It is possible there are bits in this byte on either side of the target
    // bit field that must be preserved. Get the length of each of those bit
    // fields.
    uint64_t bf_l_len = relPos;
    uint64_t bf_r_len = UINT8_BIT_LEN - (bf_l_len + bf_len);

    // Get the target bit field from the left justified inputed value.
    uint8_t bf = (i_val >> (UINT64_BIT_LEN - bf_len)) << bf_r_len;

    // Get the bit fields on either side of the target bit field.
    uint64_t bf_l_shift = UINT8_BIT_LEN - bf_l_len;
    uint64_t bf_r_shift = UINT8_BIT_LEN - bf_r_len;

    uint8_t bf_l = *relAddr;
    bf_l >>= bf_l_shift;
    bf_l <<= bf_l_shift;

    uint8_t bf_r = *relAddr;
    bf_r <<= bf_r_shift;
    bf_r >>= bf_r_shift;

    // Combine all three parts of the byte and write it out to memory.
    *relAddr = bf_l | bf | bf_r;

    // Check for any remaining bits after this target byte.
    if (0 != remain_len)
    {
        // Recursively call this function on the remaining bits.
        setFieldLeft(i_pos + bf_len, remain_len, i_val << bf_len);
    }
}

//------------------------------------------------------------------------------

void BitString::setPattern(uint64_t i_sPos, uint64_t i_sLen, uint64_t i_pattern,
                           uint64_t i_pLen)
{

    HEI_ASSERT(nullptr != getBufAddr());        // must to have a valid address
    HEI_ASSERT(0 < i_sLen);                     // must have at least one bit
    HEI_ASSERT(i_sPos + i_sLen <= getBitLen()); // field must be within range
    HEI_ASSERT(0 < i_pLen);                     // must have at least one bit
    HEI_ASSERT(i_pLen <= UINT64_BIT_LEN);       // i_pLen length must be valid

    // Get a bit string for the pattern subset (right justified).
    // Note that we cannot use a BitStringBuffer here because this function
    // could be used in the constructor of BitStringBuffer, which could causes
    // an infinite loop.
    uint8_t a[sizeof(i_pattern)] = {};
    BitString bs{sizeof(i_pattern) * 8, a};
    bs.setFieldRight(0, i_pLen, i_pattern);

    // Iterate the range in chunks the size of i_pLen.
    uint64_t endPos = i_sPos + i_sLen;
    for (uint64_t pos = i_sPos; pos < endPos; pos += i_pLen)
    {
        // The true chunk size is either i_pLen or the leftovers at the end.
        uint64_t len = std::min(i_pLen, endPos - pos);

        // Get this chunk's pattern value, truncate (right justified) if needed.
        uint64_t pattern = bs.getFieldRight(0, len);

        // Set the pattern in this string.
        setFieldRight(pos, len, pattern);
    }
}

//------------------------------------------------------------------------------

void BitString::setString(const BitString& i_sStr, uint64_t i_sPos,
                          uint64_t i_sLen, uint64_t i_dPos)
{
    // Ensure the source parameters are valid.
    HEI_ASSERT(nullptr != i_sStr.getBufAddr());
    HEI_ASSERT(0 < i_sLen); // at least one bit to copy
    HEI_ASSERT(i_sPos + i_sLen <= i_sStr.getBitLen());

    // Ensure the destination has at least one bit available to copy.
    HEI_ASSERT(nullptr != getBufAddr());
    HEI_ASSERT(i_dPos < getBitLen());

    // If the source length is greater than the destination length than the
    // extra source bits are ignored.
    uint64_t actLen = std::min(i_sLen, getBitLen() - i_dPos);

    // The bit strings may be in overlapping memory spaces. So we need to copy
    // the data in the correct direction to prevent overlapping.
    uint64_t sRelOffset = 0, dRelOffset = 0;
    uint8_t* sRelAddr = i_sStr.getRelativePosition(sRelOffset, i_sPos);
    uint8_t* dRelAddr = getRelativePosition(dRelOffset, i_dPos);

    // Copy the data.
    if ((dRelAddr == sRelAddr) && (dRelOffset == sRelOffset))
    {
        // Do nothing. The source and destination are the same.
    }
    else if ((dRelAddr < sRelAddr) ||
             ((dRelAddr == sRelAddr) && (dRelOffset < sRelOffset)))
    {
        // Copy the data forward.
        for (uint64_t pos = 0; pos < actLen; pos += UINT64_BIT_LEN)
        {
            uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN);

            uint64_t value = i_sStr.getFieldRight(i_sPos + pos, len);
            setFieldRight(i_dPos + pos, len, value);
        }
    }
    else // Copy the data backwards.
    {
        // Get the first position of the last chunk (byte aligned).
        uint64_t lastPos = ((actLen - 1) / UINT64_BIT_LEN) * UINT64_BIT_LEN;

        // Start with the last chunk and work backwards.
        for (int32_t pos = lastPos; 0 <= pos; pos -= UINT64_BIT_LEN)
        {
            uint64_t len   = std::min(actLen - pos, UINT64_BIT_LEN);
            uint64_t value = i_sStr.getFieldRight(i_sPos + pos, len);
            setFieldRight(i_dPos + pos, len, value);
        }
    }
}

//------------------------------------------------------------------------------

void BitString::maskString(const BitString& i_mask)
{
    // Get the length of the smallest string.
    uint64_t actLen = std::min(getBitLen(), i_mask.getBitLen());

    for (uint64_t pos = 0; pos < actLen; pos += UINT64_BIT_LEN)
    {
        uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN);

        uint64_t dVal = getFieldRight(pos, len);
        uint64_t sVal = i_mask.getFieldRight(pos, len);

        setFieldRight(pos, len, dVal & ~sVal);
    }
}

//------------------------------------------------------------------------------

bool BitString::isEqual(const BitString& i_str) const
{
    if (getBitLen() != i_str.getBitLen())
        return false; // size not equal

    for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN)
    {
        uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN);

        if (getFieldRight(pos, len) != i_str.getFieldRight(pos, len))
            return false; // bit strings do not match
    }

    return true; // bit strings match
}

//------------------------------------------------------------------------------

bool BitString::isZero() const
{
    for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN)
    {
        uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN);

        if (0 != getFieldRight(pos, len))
            return false; // something is non-zero
    }

    return true; // everything was zero
}

//------------------------------------------------------------------------------

uint64_t BitString::getSetCount(uint64_t i_pos, uint64_t i_len) const
{
    uint64_t endPos = i_pos + i_len;

    HEI_ASSERT(endPos <= getBitLen());

    uint64_t count = 0;

    for (uint64_t i = i_pos; i < endPos; i++)
    {
        if (isBitSet(i))
            count++;
    }

    return count;
}

//------------------------------------------------------------------------------

BitStringBuffer BitString::operator~() const
{
    BitStringBuffer bsb(getBitLen());

    for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN)
    {
        uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN);

        uint64_t dVal = getFieldRight(pos, len);

        bsb.setFieldRight(pos, len, ~dVal);
    }

    return bsb;
}

//------------------------------------------------------------------------------

BitStringBuffer BitString::operator&(const BitString& i_bs) const
{
    // Get the length of the smallest string.
    uint64_t actLen = std::min(getBitLen(), i_bs.getBitLen());

    BitStringBuffer bsb(actLen);

    for (uint64_t pos = 0; pos < actLen; pos += UINT64_BIT_LEN)
    {
        uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN);

        uint64_t dVal = getFieldRight(pos, len);
        uint64_t sVal = i_bs.getFieldRight(pos, len);

        bsb.setFieldRight(pos, len, dVal & sVal);
    }

    return bsb;
}

//------------------------------------------------------------------------------

BitStringBuffer BitString::operator|(const BitString& i_bs) const
{
    // Get the length of the smallest string.
    uint64_t actLen = std::min(getBitLen(), i_bs.getBitLen());

    BitStringBuffer bsb(actLen);

    for (uint64_t pos = 0; pos < actLen; pos += UINT64_BIT_LEN)
    {
        uint64_t len = std::min(actLen - pos, UINT64_BIT_LEN);

        uint64_t dVal = getFieldRight(pos, len);
        uint64_t sVal = i_bs.getFieldRight(pos, len);

        bsb.setFieldRight(pos, len, dVal | sVal);
    }

    return bsb;
}

//------------------------------------------------------------------------------

BitStringBuffer BitString::operator>>(uint64_t i_shift) const
{
    BitStringBuffer bsb(getBitLen()); // default all zeros

    if (i_shift < getBitLen())
    {
        // bso overlays bsb, containing the shifted offset.
        BitString bso(bsb.getBitLen() - i_shift, bsb.getBufAddr(), i_shift);

        // Copy this into bso.
        bso.setString(*this);
    }

    return bsb;
}

//------------------------------------------------------------------------------

BitStringBuffer BitString::operator<<(uint64_t i_shift) const
{
    BitStringBuffer bsb(getBitLen()); // default all zeros

    if (i_shift < getBitLen())
    {
        // bso overlays *this, containing the shifted offset.
        BitString bso(this->getBitLen() - i_shift, this->getBufAddr(), i_shift);

        // Copy bso into bsb.
        bsb.setString(bso);
    }

    return bsb;
}

//------------------------------------------------------------------------------

uint8_t* BitString::getRelativePosition(uint64_t& o_relPos,
                                        uint64_t i_absPos) const
{
    HEI_ASSERT(nullptr != getBufAddr()); // must to have a valid address
    HEI_ASSERT(i_absPos < getBitLen());  // must be a valid position

    o_relPos = (i_absPos + iv_offset) % UINT8_BIT_LEN;

    return ((uint8_t*)iv_bufAddr + ((i_absPos + iv_offset) / UINT8_BIT_LEN));
}

//##############################################################################
//                          BitStringBuffer class
//##############################################################################

BitStringBuffer::BitStringBuffer(uint64_t i_bitLen) :
    BitString(i_bitLen, nullptr)
{
    initBuffer();
}

//------------------------------------------------------------------------------

BitStringBuffer::~BitStringBuffer()
{
    delete[](uint8_t*) getBufAddr();
}

//------------------------------------------------------------------------------

BitStringBuffer::BitStringBuffer(const BitString& i_bs) :
    BitString(i_bs.getBitLen(), nullptr)
{
    initBuffer();
    if (!i_bs.isZero())
    {
        setString(i_bs);
    }
}

//------------------------------------------------------------------------------

BitStringBuffer::BitStringBuffer(const BitStringBuffer& i_bsb) :
    BitString(i_bsb.getBitLen(), nullptr)
{
    initBuffer();
    if (!i_bsb.isZero())
    {
        setString(i_bsb);
    }
}

//------------------------------------------------------------------------------

BitStringBuffer& BitStringBuffer::operator=(const BitString& i_bs)
{
    // The initBuffer() function will deallocate the buffer as well, however we
    // also need to deallocate the buffer here before we set the length.
    delete[](uint8_t*) getBufAddr();
    setBufAddr(nullptr);

    setBitLen(i_bs.getBitLen());
    initBuffer();
    if (!i_bs.isZero())
    {
        setString(i_bs);
    }

    return *this;
}

//------------------------------------------------------------------------------

BitStringBuffer& BitStringBuffer::operator=(const BitStringBuffer& i_bsb)
{
    if (this != &i_bsb) // Check for assignment to self
    {
        // The initBuffer() function will deallocate the buffer as well, however
        // we also need to deallocate the buffer here before we set the length.
        delete[](uint8_t*) getBufAddr();
        setBufAddr(nullptr);

        setBitLen(i_bsb.getBitLen());
        initBuffer();
        if (!i_bsb.isZero())
        {
            setString(i_bsb);
        }
    }

    return *this;
}

//------------------------------------------------------------------------------

void BitStringBuffer::initBuffer()
{
    // Deallocate the current buffer.
    delete[](uint8_t*) getBufAddr();

    // create new buffer, initialized to 0's
    setBufAddr(new uint8_t[getMinBytes(getBitLen())]());
}

} // end namespace libhei
