/*
 * 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, "BigInt"_s, NameVisibility::Visible, NameAdditionMode::WithoutStructureTransition);
    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);
}

// ------------------------------ 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())
        RELEASE_AND_RETURN(scope, JSValue::encode(JSBigInt::createFrom(vm, argument.asBoolean())));
    
    if (argument.isUndefinedOrNull() || argument.isNumber() || argument.isSymbol())
        return throwVMTypeError(&state, scope, "Invalid argument type in ToBigInt operation"_s);
    
    ASSERT(argument.isString());
    
    RELEASE_AND_RETURN(scope, 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, "Not safe integer"_s));
        
        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
