/*
 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
 *  Copyright (C) 2003, 2008, 2016 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 "NativeErrorConstructor.h"

#include "ErrorInstance.h"
#include "JSCInlines.h"
#include "NativeErrorPrototype.h"

namespace JSC {

STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NativeErrorConstructorBase);

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

static JSC_DECLARE_HOST_FUNCTION(callEvalError);
static JSC_DECLARE_HOST_FUNCTION(constructEvalError);
static JSC_DECLARE_HOST_FUNCTION(callRangeError);
static JSC_DECLARE_HOST_FUNCTION(constructRangeError);
static JSC_DECLARE_HOST_FUNCTION(callReferenceError);
static JSC_DECLARE_HOST_FUNCTION(constructReferenceError);
static JSC_DECLARE_HOST_FUNCTION(callSyntaxError);
static JSC_DECLARE_HOST_FUNCTION(constructSyntaxError);
static JSC_DECLARE_HOST_FUNCTION(callTypeError);
static JSC_DECLARE_HOST_FUNCTION(constructTypeError);
static JSC_DECLARE_HOST_FUNCTION(callURIError);
static JSC_DECLARE_HOST_FUNCTION(constructURIError);

template<ErrorType errorType>
inline EncodedJSValue NativeErrorConstructor<errorType>::constructImpl(JSGlobalObject* globalObject, CallFrame* callFrame)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSValue message = callFrame->argument(0);
    JSValue options = callFrame->argument(1);

    JSObject* newTarget = asObject(callFrame->newTarget());
    Structure* errorStructure = JSC_GET_DERIVED_STRUCTURE(vm, errorStructureWithErrorType<errorType>, newTarget, callFrame->jsCallee());
    RETURN_IF_EXCEPTION(scope, { });
    RELEASE_AND_RETURN(scope, JSValue::encode(ErrorInstance::create(globalObject, errorStructure, message, options, nullptr, TypeNothing, errorType, false)));
}

template<ErrorType errorType>
inline EncodedJSValue NativeErrorConstructor<errorType>::callImpl(JSGlobalObject* globalObject, CallFrame* callFrame)
{
    JSValue message = callFrame->argument(0);
    JSValue options = callFrame->argument(1);
    Structure* errorStructure = globalObject->errorStructure(errorType);
    return JSValue::encode(ErrorInstance::create(globalObject, errorStructure, message, options, nullptr, TypeNothing, errorType, false));
}

JSC_DEFINE_HOST_FUNCTION(callEvalError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::EvalError>::callImpl(globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(constructEvalError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::EvalError>::constructImpl(globalObject, callFrame);
}

JSC_DEFINE_HOST_FUNCTION(callRangeError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::RangeError>::callImpl(globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(constructRangeError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::RangeError>::constructImpl(globalObject, callFrame);
}

JSC_DEFINE_HOST_FUNCTION(callReferenceError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::ReferenceError>::callImpl(globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(constructReferenceError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::ReferenceError>::constructImpl(globalObject, callFrame);
}

JSC_DEFINE_HOST_FUNCTION(callSyntaxError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::SyntaxError>::callImpl(globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(constructSyntaxError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::SyntaxError>::constructImpl(globalObject, callFrame);
}

JSC_DEFINE_HOST_FUNCTION(callTypeError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::TypeError>::callImpl(globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(constructTypeError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::TypeError>::constructImpl(globalObject, callFrame);
}

JSC_DEFINE_HOST_FUNCTION(callURIError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::URIError>::callImpl(globalObject, callFrame);
}
JSC_DEFINE_HOST_FUNCTION(constructURIError, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
    return NativeErrorConstructor<ErrorType::URIError>::constructImpl(globalObject, callFrame);
}

static constexpr auto callFunction(ErrorType errorType) -> decltype(&callEvalError)
{
    switch (errorType) {
    case ErrorType::EvalError: return callEvalError;
    case ErrorType::RangeError: return callRangeError;
    case ErrorType::ReferenceError: return callReferenceError;
    case ErrorType::SyntaxError: return callSyntaxError;
    case ErrorType::TypeError: return callTypeError;
    case ErrorType::URIError: return callURIError;
    default: return nullptr;
    }
}

static constexpr auto constructFunction(ErrorType errorType) -> decltype(&constructEvalError)
{
    switch (errorType) {
    case ErrorType::EvalError: return constructEvalError;
    case ErrorType::RangeError: return constructRangeError;
    case ErrorType::ReferenceError: return constructReferenceError;
    case ErrorType::SyntaxError: return constructSyntaxError;
    case ErrorType::TypeError: return constructTypeError;
    case ErrorType::URIError: return constructURIError;
    default: return nullptr;
    }
}

template<ErrorType errorType>
NativeErrorConstructor<errorType>::NativeErrorConstructor(VM& vm, Structure* structure)
    : NativeErrorConstructorBase(vm, structure, callFunction(errorType), constructFunction(errorType))
{
}

void NativeErrorConstructorBase::finishCreation(VM& vm, NativeErrorPrototype* prototype, ErrorType errorType)
{
    Base::finishCreation(vm, 1, errorTypeName(errorType), PropertyAdditionMode::WithoutStructureTransition);
    ASSERT(inherits(info()));
    
    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
}

template class NativeErrorConstructor<ErrorType::EvalError>;
template class NativeErrorConstructor<ErrorType::RangeError>;
template class NativeErrorConstructor<ErrorType::ReferenceError>;
template class NativeErrorConstructor<ErrorType::SyntaxError>;
template class NativeErrorConstructor<ErrorType::TypeError>;
template class NativeErrorConstructor<ErrorType::URIError>;

} // namespace JSC
