/*
 * Copyright (C) 2017 Caio Lima <ticaiolima@gmail.com>
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "BigIntConstructor.h"

#include "BigIntPrototype.h"
#include "JSBigInt.h"
#include "JSCInlines.h"
#include "JSGlobalObjectFunctions.h"
#include "Lookup.h"
#include "ParseInt.h"
#include "StructureInlines.h"

namespace JSC {

static EncodedJSValue JSC_HOST_CALL bigIntConstructorFuncAsUintN(ExecState*);
static EncodedJSValue JSC_HOST_CALL bigIntConstructorFuncAsIntN(ExecState*);

} // namespace JSC

#include "BigIntConstructor.lut.h"

namespace JSC {

STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(BigIntConstructor);

const ClassInfo BigIntConstructor::s_info = { "Function", &Base::s_info, &bigIntConstructorTable, nullptr, CREATE_METHOD_TABLE(BigIntConstructor) };

/* Source for BigIntConstructor.lut.h
@begin bigIntConstructorTable
  asUintN   bigIntConstructorFuncAsUintN   DontEnum|Function 2
  asIntN    bigIntConstructorFuncAsIntN    DontEnum|Function 2
@end
*/

static EncodedJSValue JSC_HOST_CALL callBigIntConstructor(ExecState*);

BigIntConstructor::BigIntConstructor(VM& vm, Structure* structure)
    : InternalFunction(vm, structure, callBigIntConstructor, nullptr)
{
}

void BigIntConstructor::finishCreation(VM& vm, BigIntPrototype* bigIntPrototype)
{
    Base::finishCreation(vm, BigIntPrototype::info()->className);
    ASSERT(inherits(vm, info()));

    putDirectWithoutTransition(vm, vm.propertyNames->prototype, bigIntPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("BigInt"))), PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
}

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

static bool isSafeInteger(JSValue argument)
{
    if (argument.isInt32())
        return true;

    if (!argument.isDouble())
        return false;

    double number = argument.asDouble();
    return trunc(number) == number && std::abs(number) <= maxSafeInteger();
}

static EncodedJSValue toBigInt(ExecState& state, JSValue argument)
{
    ASSERT(argument.isPrimitive());
    VM& vm = state.vm();
    
    if (argument.isBigInt())
        return JSValue::encode(argument);
    
    auto scope = DECLARE_THROW_SCOPE(vm);
    
    if (argument.isBoolean()) {
        scope.release();
        return JSValue::encode(JSBigInt::createFrom(vm, argument.asBoolean()));
    }
    
    if (argument.isUndefinedOrNull() || argument.isNumber() || argument.isSymbol())
        return throwVMTypeError(&state, scope, ASCIILiteral("Invalid argument type in ToBigInt operation"));
    
    ASSERT(argument.isString());
    
    scope.release();
    return toStringView(&state, argument, [&] (StringView view) {
        return JSValue::encode(JSBigInt::parseInt(&state, view));
    });
}

static EncodedJSValue JSC_HOST_CALL callBigIntConstructor(ExecState* state)
{
    VM& vm = state->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    
    JSValue value = state->argument(0);
    JSValue primitive = value.toPrimitive(state);
    RETURN_IF_EXCEPTION(scope, encodedJSValue());

    if (primitive.isNumber()) {
        if (!isSafeInteger(primitive))
            return throwVMError(state, scope, createRangeError(state, ASCIILiteral("Not safe integer")));
        
        scope.release();
        if (primitive.isInt32())
            return JSValue::encode(JSBigInt::createFrom(vm, primitive.asInt32()));

        if (primitive.isUInt32())
            return JSValue::encode(JSBigInt::createFrom(vm, primitive.asUInt32()));

        return JSValue::encode(JSBigInt::createFrom(vm, static_cast<int64_t>(primitive.asDouble())));
    }
    
    EncodedJSValue result = toBigInt(*state, primitive);
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    return result;
}

EncodedJSValue JSC_HOST_CALL bigIntConstructorFuncAsUintN(ExecState*)
{
    // FIXME: [ESNext][BigInt] Implement BigInt.asIntN and BigInt.asUintN
    // https://bugs.webkit.org/show_bug.cgi?id=181144
    CRASH();
    return JSValue::encode(JSValue());
}

EncodedJSValue JSC_HOST_CALL bigIntConstructorFuncAsIntN(ExecState*)
{
    // FIXME: [ESNext][BigInt] Implement BigInt.asIntN and BigInt.asUintN
    // https://bugs.webkit.org/show_bug.cgi?id=181144
    CRASH();
    return JSValue::encode(JSValue());
}

} // namespace JSC
