/** @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
