/*
 *  Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org)
 *  Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 *  USA
 *
 */

#include "config.h"
#include "NumberPrototype.h"

#include "BigInteger.h"
#include "Error.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSString.h"
#include "Operations.h"
#include "Uint16WithFraction.h"
#include <wtf/dtoa.h>
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
#include <wtf/Vector.h>
#include <wtf/dtoa/double-conversion.h>

using namespace WTF::double_conversion;

// To avoid conflict with WTF::StringBuilder.
typedef WTF::double_conversion::StringBuilder DoubleConversionStringBuilder;

namespace JSC {

static EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState*);
static EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState*);
static EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState*);
static EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState*);
static EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState*);
static EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*);

}

#include "NumberPrototype.lut.h"

namespace JSC {

const ClassInfo NumberPrototype::s_info = { "Number", NumberObject::s_classinfo(), 0, ExecState::numberPrototypeTable, CREATE_METHOD_TABLE(NumberPrototype) };

/* Source for NumberPrototype.lut.h
@begin numberPrototypeTable
  toString          numberProtoFuncToString         DontEnum|Function 1
  toLocaleString    numberProtoFuncToLocaleString   DontEnum|Function 0
  valueOf           numberProtoFuncValueOf          DontEnum|Function 0
  toFixed           numberProtoFuncToFixed          DontEnum|Function 1
  toExponential     numberProtoFuncToExponential    DontEnum|Function 1
  toPrecision       numberProtoFuncToPrecision      DontEnum|Function 1
@end
*/

ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberPrototype);

NumberPrototype::NumberPrototype(ExecState* exec, Structure* structure)
    : NumberObject(exec->globalData(), structure)
{
}

void NumberPrototype::finishCreation(ExecState* exec, JSGlobalObject*)
{
    Base::finishCreation(exec->globalData());
    setInternalValue(exec->globalData(), jsNumber(0));

    ASSERT(inherits(&s_info));
}

bool NumberPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
{
    return getStaticFunctionSlot<NumberObject>(exec, ExecState::numberPrototypeTable(exec), jsCast<NumberPrototype*>(cell), propertyName, slot);
}

bool NumberPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<NumberObject>(exec, ExecState::numberPrototypeTable(exec), jsCast<NumberPrototype*>(object), propertyName, descriptor);
}

// ------------------------------ Functions ---------------------------

static ALWAYS_INLINE bool toThisNumber(JSValue thisValue, double& x)
{
    if (thisValue.isInt32()) {
        x = thisValue.asInt32();
        return true;
    }

    if (thisValue.isDouble()) {
        x = thisValue.asDouble();
        return true;
    }
    
    if (thisValue.isCell() && thisValue.asCell()->structure()->typeInfo().isNumberObject()) {
        x = static_cast<const NumberObject*>(thisValue.asCell())->internalValue().asNumber();
        return true;
    }

    return false;
}

static ALWAYS_INLINE bool getIntegerArgumentInRange(ExecState* exec, int low, int high, int& result, bool& isUndefined)
{
    result = 0;
    isUndefined = false;

    JSValue argument0 = exec->argument(0);
    if (argument0.isUndefined()) {
        isUndefined = true;
        return true;
    }

    double asDouble = argument0.toInteger(exec);
    if (asDouble < low || asDouble > high)
        return false;

    result = static_cast<int>(asDouble);
    return true;
}

// The largest finite floating point number is 1.mantissa * 2^(0x7fe-0x3ff).
// Since 2^N in binary is a one bit followed by N zero bits. 1 * 2^3ff requires
// at most 1024 characters to the left of a decimal point, in base 2 (1025 if
// we include a minus sign). For the fraction, a value with an exponent of 0
// has up to 52 bits to the right of the decimal point. Each decrement of the
// exponent down to a minimum of -0x3fe adds an additional digit to the length
// of the fraction. As such the maximum fraction size is 1075 (1076 including
// a point). We pick a buffer size such that can simply place the point in the
// center of the buffer, and are guaranteed to have enough space in each direction
// fo any number of digits an IEEE number may require to represent.
typedef char RadixBuffer[2180];

// Mapping from integers 0..35 to digit identifying this value, for radix 2..36.
static const char radixDigits[] = "0123456789abcdefghijklmnopqrstuvwxyz";

static char* toStringWithRadix(RadixBuffer& buffer, double number, unsigned radix)
{
    ASSERT(isfinite(number));
    ASSERT(radix >= 2 && radix <= 36);

    // Position the decimal point at the center of the string, set
    // the startOfResultString pointer to point at the decimal point.
    char* decimalPoint = buffer + sizeof(buffer) / 2;
    char* startOfResultString = decimalPoint;

    // Extract the sign.
    bool isNegative = number < 0;
    if (signbit(number))
        number = -number;
    double integerPart = floor(number);

    // We use this to test for odd values in odd radix bases.
    // Where the base is even, (e.g. 10), to determine whether a value is even we need only
    // consider the least significant digit. For example, 124 in base 10 is even, because '4'
    // is even. if the radix is odd, then the radix raised to an integer power is also odd.
    // E.g. in base 5, 124 represents (1 * 125 + 2 * 25 + 4 * 5). Since each digit in the value
    // is multiplied by an odd number, the result is even if the sum of all digits is even.
    //
    // For the integer portion of the result, we only need test whether the integer value is
    // even or odd. For each digit of the fraction added, we should invert our idea of whether
    // the number is odd if the new digit is odd.
    //
    // Also initialize digit to this value; for even radix values we only need track whether
    // the last individual digit was odd.
    bool integerPartIsOdd = integerPart <= static_cast<double>(0x1FFFFFFFFFFFFFull) && static_cast<int64_t>(integerPart) & 1;
    ASSERT(integerPartIsOdd == static_cast<bool>(fmod(integerPart, 2)));
    bool isOddInOddRadix = integerPartIsOdd;
    uint32_t digit = integerPartIsOdd;

    // Check if the value has a fractional part to convert.
    double fractionPart = number - integerPart;
    if (fractionPart) {
        // Write the decimal point now.
        *decimalPoint = '.';

        // Higher precision representation of the fractional part.
        Uint16WithFraction fraction(fractionPart);

        bool needsRoundingUp = false;
        char* endOfResultString = decimalPoint + 1;

        // Calculate the delta from the current number to the next & previous possible IEEE numbers.
        double nextNumber = nextafter(number, std::numeric_limits<double>::infinity());
        double lastNumber = nextafter(number, -std::numeric_limits<double>::infinity());
        ASSERT(isfinite(nextNumber) && !signbit(nextNumber));
        ASSERT(isfinite(lastNumber) && !signbit(lastNumber));
        double deltaNextDouble = nextNumber - number;
        double deltaLastDouble = number - lastNumber;
        ASSERT(isfinite(deltaNextDouble) && !signbit(deltaNextDouble));
        ASSERT(isfinite(deltaLastDouble) && !signbit(deltaLastDouble));

        // We track the delta from the current value to the next, to track how many digits of the
        // fraction we need to write. For example, if the value we are converting is precisely
        // 1.2345, so far we have written the digits "1.23" to a string leaving a remainder of
        // 0.45, and we want to determine whether we can round off, or whether we need to keep
        // appending digits ('4'). We can stop adding digits provided that then next possible
        // lower IEEE value is further from 1.23 than the remainder we'd be rounding off (0.45),
        // which is to say, less than 1.2255. Put another way, the delta between the prior
        // possible value and this number must be more than 2x the remainder we'd be rounding off
        // (or more simply half the delta between numbers must be greater than the remainder).
        //
        // Similarly we need track the delta to the next possible value, to dertermine whether
        // to round up. In almost all cases (other than at exponent boundaries) the deltas to
        // prior and subsequent values are identical, so we don't need track then separately.
        if (deltaNextDouble != deltaLastDouble) {
            // Since the deltas are different track them separately. Pre-multiply by 0.5.
            Uint16WithFraction halfDeltaNext(deltaNextDouble, 1);
            Uint16WithFraction halfDeltaLast(deltaLastDouble, 1);

            while (true) {
                // examine the remainder to determine whether we should be considering rounding
                // up or down. If remainder is precisely 0.5 rounding is to even.
                int dComparePoint5 = fraction.comparePoint5();
                if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) {
                    // Check for rounding up; are we closer to the value we'd round off to than
                    // the next IEEE value would be?
                    if (fraction.sumGreaterThanOne(halfDeltaNext)) {
                        needsRoundingUp = true;
                        break;
                    }
                } else {
                    // Check for rounding down; are we closer to the value we'd round off to than
                    // the prior IEEE value would be?
                    if (fraction < halfDeltaLast)
                        break;
                }

                ASSERT(endOfResultString < (buffer + sizeof(buffer) - 1));
                // Write a digit to the string.
                fraction *= radix;
                digit = fraction.floorAndSubtract();
                *endOfResultString++ = radixDigits[digit];
                // Keep track whether the portion written is currently even, if the radix is odd.
                if (digit & 1)
                    isOddInOddRadix = !isOddInOddRadix;

                // Shift the fractions by radix.
                halfDeltaNext *= radix;
                halfDeltaLast *= radix;
            }
        } else {
            // This code is identical to that above, except since deltaNextDouble != deltaLastDouble
            // we don't need to track these two values separately.
            Uint16WithFraction halfDelta(deltaNextDouble, 1);

            while (true) {
                int dComparePoint5 = fraction.comparePoint5();
                if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) {
                    if (fraction.sumGreaterThanOne(halfDelta)) {
                        needsRoundingUp = true;
                        break;
                    }
                } else if (fraction < halfDelta)
                    break;

                ASSERT(endOfResultString < (buffer + sizeof(buffer) - 1));
                fraction *= radix;
                digit = fraction.floorAndSubtract();
                if (digit & 1)
                    isOddInOddRadix = !isOddInOddRadix;
                *endOfResultString++ = radixDigits[digit];

                halfDelta *= radix;
            }
        }

        // Check if the fraction needs rounding off (flag set in the loop writing digits, above).
        if (needsRoundingUp) {
            // Whilst the last digit is the maximum in the current radix, remove it.
            // e.g. rounding up the last digit in "12.3999" is the same as rounding up the
            // last digit in "12.3" - both round up to "12.4".
            while (endOfResultString[-1] == radixDigits[radix - 1])
                --endOfResultString;

            // Radix digits are sequential in ascii/unicode, except for '9' and 'a'.
            // E.g. the first 'if' case handles rounding 67.89 to 67.8a in base 16.
            // The 'else if' case handles rounding of all other digits.
            if (endOfResultString[-1] == '9')
                endOfResultString[-1] = 'a';
            else if (endOfResultString[-1] != '.')
                ++endOfResultString[-1];
            else {
                // One other possibility - there may be no digits to round up in the fraction
                // (or all may be been rounded off already), in which case we may need to
                // round into the integer portion of the number. Remove the decimal point.
                --endOfResultString;
                // In order to get here there must have been a non-zero fraction, in which case
                // there must be at least one bit of the value's mantissa not in use in the
                // integer part of the number. As such, adding to the integer part should not
                // be able to lose precision.
                ASSERT((integerPart + 1) - integerPart == 1);
                ++integerPart;
            }
        } else {
            // We only need to check for trailing zeros if the value does not get rounded up.
            while (endOfResultString[-1] == '0')
                --endOfResultString;
        }

        *endOfResultString = '\0';
        ASSERT(endOfResultString < buffer + sizeof(buffer));
    } else
        *decimalPoint = '\0';

    BigInteger units(integerPart);

    // Always loop at least once, to emit at least '0'.
    do {
        ASSERT(buffer < startOfResultString);

        // Read a single digit and write it to the front of the string.
        // Divide by radix to remove one digit from the value.
        digit = units.divide(radix);
        *--startOfResultString = radixDigits[digit];
    } while (!!units);

    // If the number is negative, prepend '-'.
    if (isNegative)
        *--startOfResultString = '-';
    ASSERT(buffer <= startOfResultString);

    return startOfResultString;
}

static String toStringWithRadix(int32_t number, unsigned radix)
{
    LChar buf[1 + 32]; // Worst case is radix == 2, which gives us 32 digits + sign.
    LChar* end = buf + WTF_ARRAY_LENGTH(buf);
    LChar* p = end;

    bool negative = false;
    uint32_t positiveNumber = number;
    if (number < 0) {
        negative = true;
        positiveNumber = -number;
    }

    while (positiveNumber) {
        uint32_t index = positiveNumber % radix;
        ASSERT(index < sizeof(radixDigits));
        *--p = static_cast<LChar>(radixDigits[index]);
        positiveNumber /= radix;
    }
    if (negative)
        *--p = '-';

    return String(p, static_cast<unsigned>(end - p));
}

// toExponential converts a number to a string, always formatting as an expoential.
// This method takes an optional argument specifying a number of *decimal places*
// to round the significand to (or, put another way, this method optionally rounds
// to argument-plus-one significant figures).
EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
{
    double x;
    if (!toThisNumber(exec->hostThisValue(), x))
        return throwVMTypeError(exec);

    // Get the argument. 
    int decimalPlacesInExponent;
    bool isUndefined;
    if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlacesInExponent, isUndefined))
        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toExponential() argument must be between 0 and 20")));

    // Handle NaN and Infinity.
    if (!isfinite(x))
        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));

    // Round if the argument is not undefined, always format as exponential.
    char buffer[WTF::NumberToStringBufferLength];
    DoubleConversionStringBuilder builder(buffer, WTF::NumberToStringBufferLength);
    const DoubleToStringConverter& converter = DoubleToStringConverter::EcmaScriptConverter();
    builder.Reset();
    isUndefined
        ? converter.ToExponential(x, -1, &builder)
        : converter.ToExponential(x, decimalPlacesInExponent, &builder);
    return JSValue::encode(jsString(exec, String(builder.Finalize())));
}

// toFixed converts a number to a string, always formatting as an a decimal fraction.
// This method takes an argument specifying a number of decimal places to round the
// significand to. However when converting large values (1e+21 and above) this
// method will instead fallback to calling ToString. 
EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
{
    double x;
    if (!toThisNumber(exec->hostThisValue(), x))
        return throwVMTypeError(exec);

    // Get the argument. 
    int decimalPlaces;
    bool isUndefined; // This is ignored; undefined treated as 0.
    if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlaces, isUndefined))
        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toFixed() argument must be between 0 and 20")));

    // 15.7.4.5.7 states "If x >= 10^21, then let m = ToString(x)"
    // This also covers Ininity, and structure the check so that NaN
    // values are also handled by numberToString
    if (!(fabs(x) < 1e+21))
        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));

    // The check above will return false for NaN or Infinity, these will be
    // handled by numberToString.
    ASSERT(isfinite(x));

    NumberToStringBuffer buffer;
    return JSValue::encode(jsString(exec, String(numberToFixedWidthString(x, decimalPlaces, buffer))));
}

// toPrecision converts a number to a string, takeing an argument specifying a
// number of significant figures to round the significand to. For positive
// exponent, all values that can be represented using a decimal fraction will
// be, e.g. when rounding to 3 s.f. any value up to 999 will be formated as a
// decimal, whilst 1000 is converted to the exponential representation 1.00e+3.
// For negative exponents values >= 1e-6 are formated as decimal fractions,
// with smaller values converted to exponential representation.
EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
{
    double x;
    if (!toThisNumber(exec->hostThisValue(), x))
        return throwVMTypeError(exec);

    // Get the argument. 
    int significantFigures;
    bool isUndefined;
    if (!getIntegerArgumentInRange(exec, 1, 21, significantFigures, isUndefined))
        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toPrecision() argument must be between 1 and 21")));

    // To precision called with no argument is treated as ToString.
    if (isUndefined)
        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));

    // Handle NaN and Infinity.
    if (!isfinite(x))
        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));

    NumberToStringBuffer buffer;
    return JSValue::encode(jsString(exec, String(numberToFixedPrecisionString(x, significantFigures, buffer))));
}

static inline int32_t extractRadixFromArgs(ExecState* exec)
{
    JSValue radixValue = exec->argument(0);
    int32_t radix;
    if (radixValue.isInt32())
        radix = radixValue.asInt32();
    else if (radixValue.isUndefined())
        radix = 10;
    else
        radix = static_cast<int32_t>(radixValue.toInteger(exec)); // nan -> 0

    return radix;
}

static inline EncodedJSValue integerValueToString(ExecState* exec, int32_t radix, int32_t value)
{
    // A negative value casted to unsigned would be bigger than 36 (the max radix).
    if (static_cast<unsigned>(value) < static_cast<unsigned>(radix)) {
        ASSERT(value <= 36);
        ASSERT(value >= 0);
        JSGlobalData* globalData = &exec->globalData();
        return JSValue::encode(globalData->smallStrings.singleCharacterString(globalData, radixDigits[value]));
    }

    if (radix == 10) {
        JSGlobalData* globalData = &exec->globalData();
        return JSValue::encode(jsString(globalData, globalData->numericStrings.add(value)));
    }

    return JSValue::encode(jsString(exec, toStringWithRadix(value, radix)));

}

EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec)
{
    double doubleValue;
    if (!toThisNumber(exec->hostThisValue(), doubleValue))
        return throwVMTypeError(exec);

    int32_t radix = extractRadixFromArgs(exec);
    if (radix < 2 || radix > 36)
        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36")));

    int32_t integerValue = static_cast<int32_t>(doubleValue);
    if (integerValue == doubleValue)
        return integerValueToString(exec, radix, integerValue);

    if (radix == 10) {
        JSGlobalData* globalData = &exec->globalData();
        return JSValue::encode(jsString(globalData, globalData->numericStrings.add(doubleValue)));
    }

    if (!isfinite(doubleValue))
        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(doubleValue)));

    RadixBuffer s;
    return JSValue::encode(jsString(exec, toStringWithRadix(s, doubleValue, radix)));
}

EncodedJSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec)
{
    double x;
    if (!toThisNumber(exec->hostThisValue(), x))
        return throwVMTypeError(exec);

    return JSValue::encode(jsNumber(x).toString(exec));
}

EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec)
{
    double x;
    if (!toThisNumber(exec->hostThisValue(), x))
        return throwVMTypeError(exec);
    return JSValue::encode(jsNumber(x));
}

} // namespace JSC
