#include "bej_common.h"

#include <float.h>
#include <inttypes.h>
#include <stdio.h>

uint64_t bejGetUnsignedInteger(const uint8_t* bytes, uint8_t numOfBytes)
{
    uint64_t num = 0;
    for (uint8_t i = 0; i < numOfBytes; ++i)
    {
        num |= (uint64_t)(*(bytes + i)) << (i * 8);
    }
    return num;
}

uint64_t bejGetNnint(const uint8_t* nnint)
{
    // In nnint, first byte indicate how many bytes are there. Remaining bytes
    // represent the value in little-endian format.
    const uint8_t size = *nnint;
    return bejGetUnsignedInteger(nnint + sizeof(uint8_t), size);
}

uint8_t bejGetNnintSize(const uint8_t* nnint)
{
    // In nnint, first byte indicate how many bytes are there.
    return *nnint + sizeof(uint8_t);
}

uint8_t bejIntLengthOfValue(int64_t val)
{
    // Only need to encode 0x00 or 0xFF
    if (val == 0 || val == -1)
    {
        return 1;
    }

    // Starts at the MSB. LSB index is 0.
    uint8_t byteIndex = sizeof(uint64_t) - 1;
    const uint8_t bitsPerByte = 8;
    // The current byte being looked at. Starts at MSB.
    uint8_t currentByte = (val >> (bitsPerByte * byteIndex)) & 0xFF;
    uint8_t byteLength = sizeof(int64_t);

    while ((val > 0 && currentByte == 0) || (val < 0 && currentByte == 0xFF))
    {
        byteLength--;
        byteIndex--;
        currentByte = (val >> (bitsPerByte * byteIndex)) & 0xFF;
    }

    // If the value is positive and encoded MSBbit is 1 we need to add 0x00 to
    // the encoded value as padding.
    if (val > 0 && (currentByte & 0x80))
    {
        byteLength++;
    }

    // If the value is negative and encoded MSBbit is 0 we need to add 0xFF to
    // the encoded value as padding.
    if (val < 0 && !(currentByte & 0x80))
    {
        byteLength++;
    }

    return byteLength;
}

uint8_t bejNnintEncodingSizeOfUInt(uint64_t val)
{
    uint8_t bytes = 0;
    do
    {
        // Even if the value is 0, we need a byte for that.
        ++bytes;
        val = val >> 8;
    } while (val != 0);
    // Need 1 byte to add the nnint length.
    return bytes + 1;
}

uint8_t bejNnintLengthFieldOfUInt(uint64_t val)
{
    // From the size of the encoded value, we need 1 byte for the length field.
    return bejNnintEncodingSizeOfUInt(val) - 1;
}

double bejFabs(double x)
{
    return (x < 0) ? -x : x;
}

double bejModf(double x, double* integer)
{
    // x expected to be within int64_t max value.
    int64_t i = (int64_t)x;
    *integer = (double)i;
    return x - *integer;
}

int bejGetDoubleFromBejReal(const struct BejReal* value, double* output)
{
// Maximum supported zero count in BejReal type. The value selected will prevent
// overflow of divisor(uin64_t). We could support larger zero count but that
// will require more computational logic and we probably do not need that level
// of precision.
#define BEJ_REAL_MAX_SUPPORTED_ZERO_COUNT 19

// Maximum value possible for the uint64_t divisor used.
#define BEJ_UINT64_DIVISOR_MAX ((uint64_t)10000000000000000000ULL)

    if (value->zeroCount > BEJ_REAL_MAX_SUPPORTED_ZERO_COUNT)
    {
        fprintf(stderr,
                "Provided zero count: %" PRIu64 " exceeds supported: %u\n",
                value->zeroCount, BEJ_REAL_MAX_SUPPORTED_ZERO_COUNT);
        return -1;
    }

    // Initialize the multiplication or division factor based on exponent
    double exp_factor = 1.00;
    for (int64_t exp = bejFabs(value->exp); exp > 0; --exp)
    {
        // Check if the multiplication factor is larger than what can be
        // supported.
        if (exp_factor > (DBL_MAX / 10.0))
        {
            fprintf(stderr, "Multiplication factor derived from exp is larger "
                            "than a double\n");
            return -1;
        }
        exp_factor *= 10;
    }

    // The double value will be formed as follows:
    // value.whole = 1
    // value.zeroCount = 3
    // value.fract = 525
    // output = whole.[zero_count][fractional_part] ==> 1.000525.
    // Then the exponent will be applied.
    // output /* 10^(exp)

    // Get the whole value.
    *output = value->whole;

    // Calculating the divisor needed to divide the fract. Check for divisor
    // overflow.
    uint64_t divisor = 1;
    while (divisor <= value->fract && (divisor < BEJ_UINT64_DIVISOR_MAX))
    {
        divisor *= 10;
    }

    double fraction = (double)value->fract / divisor;
    // In case divisor was going to overflow, we need to divide fraction by an
    // additional 10.
    if (divisor == BEJ_UINT64_DIVISOR_MAX)
    {
        fraction /= 10;
    }

    // Then we need to divide the fractional part by the number of zeros.
    // Calculating the divisor for that. Divisor will not overflow since we have
    // limit the zero count.
    divisor = 1;
    for (uint64_t zeroCount = value->zeroCount; zeroCount > 0; --zeroCount)
    {
        divisor *= 10;
    }
    fraction /= divisor;

    // "fract" part doesn't include the sign. We need to use the sign of the
    // "whole". The current representation doesn't support negative values less
    // than 0 and greater then -1. That means if the whole part is 0, then sign
    // will be always +.
    fraction *= ((value->whole < 0) ? -1 : 1);
    *output += fraction;

    if (value->exp > 0)
    {
        // Check if the result is larger than a double
        if (*output > (DBL_MAX / exp_factor))
        {
            fprintf(stderr, "Result is larger than a double\n");
            return -1;
        }
        *output *= exp_factor;
    }
    // Using else if to avoid unnecessary division if exp == 0.
    else if (value->exp < 0)
    {
        *output /= exp_factor;
    }

    return 0;
}
