/*
 * Copyright (C) 2019 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.
 */

#import "config.h"
#import "JSAPIGlobalObject.h"

#if JSC_OBJC_API_ENABLED

#import "APICast.h"
#import "CallFrameInlines.h"
#import "CatchScope.h"
#import "Completion.h"
#import "Error.h"
#import "Exception.h"
#import "JSContextInternal.h"
#import "JSInternalPromise.h"
#import "JSModuleLoader.h"
#import "JSNativeStdFunction.h"
#import "JSPromise.h"
#import "JSScriptInternal.h"
#import "JSSourceCode.h"
#import "JSValueInternal.h"
#import "JSVirtualMachineInternal.h"
#import "JavaScriptCore.h"
#import "ObjectConstructor.h"
#import "SourceOrigin.h"
#import <wtf/URL.h>

namespace JSC {

const ClassInfo JSAPIGlobalObject::s_info = { "GlobalObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAPIGlobalObject) };

const GlobalObjectMethodTable JSAPIGlobalObject::s_globalObjectMethodTable = {
    &supportsRichSourceInfo,
    &shouldInterruptScript,
    &javaScriptRuntimeFlags,
    nullptr, // queueTaskToEventLoop
    &shouldInterruptScriptBeforeTimeout,
    &moduleLoaderImportModule, // moduleLoaderImportModule
    &moduleLoaderResolve, // moduleLoaderResolve
    &moduleLoaderFetch, // moduleLoaderFetch
    &moduleLoaderCreateImportMetaProperties, // moduleLoaderCreateImportMetaProperties
    moduleLoaderEvaluate, // moduleLoaderEvaluate
    nullptr, // promiseRejectionTracker
    nullptr, // defaultLanguage
    nullptr, // compileStreaming
    nullptr, // instantiateStreaming
};

static Expected<URL, String> computeValidImportSpecifier(const URL& base, const String& specifier)
{
    URL absoluteURL(URL(), specifier);
    if (absoluteURL.isValid())
        return absoluteURL;

    if (!specifier.startsWith('/') && !specifier.startsWith("./") && !specifier.startsWith("../"))
        return makeUnexpected(makeString("Module specifier: "_s, specifier, " does not start with \"/\", \"./\", or \"../\"."_s));

    if (specifier.startsWith('/')) {
        absoluteURL = URL(URL({ }, "file://"), specifier);
        if (absoluteURL.isValid())
            return absoluteURL;
    }

    if (base == URL())
        return makeUnexpected("Could not determine the base URL for loading."_s);

    if (!base.isValid())
        return makeUnexpected(makeString("Referrering script's url is not valid: "_s, base.string()));

    absoluteURL = URL(base, specifier);
    if (absoluteURL.isValid())
        return absoluteURL;
    return makeUnexpected(makeString("Could not form valid URL from identifier and base. Tried:"_s, absoluteURL.string()));
}

Identifier JSAPIGlobalObject::moduleLoaderResolve(JSGlobalObject* globalObject, JSModuleLoader*, JSValue key, JSValue referrer, JSValue)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    ASSERT_UNUSED(globalObject, globalObject == globalObject);
    ASSERT(key.isString() || key.isSymbol());
    String name =  key.toWTFString(globalObject);
    RETURN_IF_EXCEPTION(scope, { });

    URL base;
    if (JSString* referrerString = jsDynamicCast<JSString*>(vm, referrer)) {
        String value = referrerString->value(globalObject);
        RETURN_IF_EXCEPTION(scope, { });
        URL referrerURL({ }, value);
        RELEASE_ASSERT(referrerURL.isValid());
        base = WTFMove(referrerURL);
    }

    auto result = computeValidImportSpecifier(base, name);
    if (result)
        return Identifier::fromString(vm, result.value());

    throwVMError(globalObject, scope, createError(globalObject, result.error()));
    return { };
}

JSInternalPromise* JSAPIGlobalObject::moduleLoaderImportModule(JSGlobalObject* globalObject, JSModuleLoader*, JSString* specifierValue, JSValue, const SourceOrigin& sourceOrigin)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_CATCH_SCOPE(vm);
    auto reject = [&] (JSValue exception) -> JSInternalPromise* {
        scope.clearException();
        auto* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure());
        // FIXME: We could have error since any JS call can throw stack-overflow errors.
        // https://bugs.webkit.org/show_bug.cgi?id=203402
        promise->reject(globalObject, exception);
        scope.clearException();
        return promise;
    };

    auto import = [&] (URL& url) {
        auto result = importModule(globalObject, Identifier::fromString(vm, url), jsUndefined(), jsUndefined());
        if (UNLIKELY(scope.exception()))
            return reject(scope.exception());
        return result;
    };

    auto specifier = specifierValue->value(globalObject);
    if (UNLIKELY(scope.exception())) {
        JSValue exception = scope.exception();
        scope.clearException();
        return reject(exception);
    }

    String referrer = !sourceOrigin.isNull() ? sourceOrigin.string() : String();
    URL baseURL(URL(), referrer);
    auto result = computeValidImportSpecifier(baseURL, specifier);
    if (result)
        return import(result.value());
    return reject(createError(globalObject, result.error()));
}

JSInternalPromise* JSAPIGlobalObject::moduleLoaderFetch(JSGlobalObject* globalObject, JSModuleLoader*, JSValue key, JSValue, JSValue)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_CATCH_SCOPE(vm);

    ASSERT(globalObject == globalObject);
    JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject)];

    JSInternalPromise* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure());

    Identifier moduleKey = key.toPropertyKey(globalObject);
    if (UNLIKELY(scope.exception())) {
        JSValue exception = scope.exception();
        scope.clearException();
        promise->reject(globalObject, exception);
        scope.clearException();
        return promise;
    }

    if (UNLIKELY(![context moduleLoaderDelegate])) {
        promise->reject(globalObject, createError(globalObject, "No module loader provided."));
        return promise;
    }

    auto strongPromise = Strong<JSInternalPromise>(vm, promise);
    auto* resolve = JSNativeStdFunction::create(vm, globalObject, 1, "resolve", [=] (JSGlobalObject* globalObject, CallFrame* callFrame) {
        // This captures the globalObject but that's ok because our structure keeps it alive anyway.
        VM& vm = globalObject->vm();
        JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject)];
        id script = valueToObject(context, toRef(globalObject, callFrame->argument(0)));

        MarkedArgumentBuffer args;

        auto rejectPromise = [&] (String message) {
            strongPromise.get()->reject(globalObject, createTypeError(globalObject, message));
            return encodedJSUndefined();
        };

        if (UNLIKELY(![script isKindOfClass:[JSScript class]]))
            return rejectPromise("First argument of resolution callback is not a JSScript"_s);

        JSScript* jsScript = static_cast<JSScript *>(script);

        JSSourceCode* source = [jsScript jsSourceCode];
        if (UNLIKELY([jsScript type] != kJSScriptTypeModule))
            return rejectPromise("The JSScript that was provided did not have expected type of kJSScriptTypeModule."_s);

        NSURL *sourceURL = [jsScript sourceURL];
        String oldModuleKey { [sourceURL absoluteString] };
        if (UNLIKELY(Identifier::fromString(vm, oldModuleKey) != moduleKey))
            return rejectPromise(makeString("The same JSScript was provided for two different identifiers, previously: ", oldModuleKey, " and now: ", moduleKey.string()));

        strongPromise.get()->resolve(globalObject, source);
        return encodedJSUndefined();
    });

    auto* reject = JSNativeStdFunction::create(vm, globalObject, 1, "reject", [=] (JSGlobalObject*, CallFrame* callFrame) {
        strongPromise.get()->reject(globalObject, callFrame->argument(0));
        return encodedJSUndefined();
    });

    [[context moduleLoaderDelegate] context:context fetchModuleForIdentifier:[::JSValue valueWithJSValueRef:toRef(globalObject, key) inContext:context] withResolveHandler:[::JSValue valueWithJSValueRef:toRef(globalObject, resolve) inContext:context] andRejectHandler:[::JSValue valueWithJSValueRef:toRef(globalObject, reject) inContext:context]];
    if (context.exception) {
        promise->reject(globalObject, toJS(globalObject, [context.exception JSValueRef]));
        context.exception = nil;
    }
    return promise;
}

JSObject* JSAPIGlobalObject::moduleLoaderCreateImportMetaProperties(JSGlobalObject* globalObject, JSModuleLoader*, JSValue key, JSModuleRecord*, JSValue)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSObject* metaProperties = constructEmptyObject(vm, globalObject->nullPrototypeObjectStructure());
    RETURN_IF_EXCEPTION(scope, nullptr);

    metaProperties->putDirect(vm, Identifier::fromString(vm, "filename"), key);
    RETURN_IF_EXCEPTION(scope, nullptr);

    return metaProperties;
}

JSValue JSAPIGlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject, JSModuleLoader* moduleLoader, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher)
{
    VM& vm = globalObject->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject)];
    id <JSModuleLoaderDelegate> moduleLoaderDelegate = [context moduleLoaderDelegate];
    NSURL *url = nil;

    if ([moduleLoaderDelegate respondsToSelector:@selector(willEvaluateModule:)] || [moduleLoaderDelegate respondsToSelector:@selector(didEvaluateModule:)]) {
        String moduleKey = key.toWTFString(globalObject);
        RETURN_IF_EXCEPTION(scope, { });
        url = [NSURL URLWithString:static_cast<NSString *>(moduleKey)];
    }

    if ([moduleLoaderDelegate respondsToSelector:@selector(willEvaluateModule:)])
        [moduleLoaderDelegate willEvaluateModule:url];

    scope.release();
    JSValue result = moduleLoader->evaluateNonVirtual(globalObject, key, moduleRecordValue, scriptFetcher);

    if ([moduleLoaderDelegate respondsToSelector:@selector(didEvaluateModule:)])
        [moduleLoaderDelegate didEvaluateModule:url];

    return result;
}

JSValue JSAPIGlobalObject::loadAndEvaluateJSScriptModule(const JSLockHolder&, JSScript *script)
{
    ASSERT(script.type == kJSScriptTypeModule);
    VM& vm = this->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    Identifier key = Identifier::fromString(vm, String { [[script sourceURL] absoluteString] });
    JSInternalPromise* promise = importModule(this, key, jsUndefined(), jsUndefined());
    RETURN_IF_EXCEPTION(scope, { });
    auto* result = JSPromise::create(vm, this->promiseStructure());
    result->resolve(this, promise);
    RETURN_IF_EXCEPTION(scope, { });
    return result;
}

}

#endif // JSC_OBJC_API_ENABLED
