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

#include <util/hei_bit_string.hpp>

#include <hei_user_defines.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
