/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 * Copyright (C) 2012 Michael Pruett <michael@68k.org>
 * Copyright (C) 2014-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 AND ITS CONTRIBUTORS "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 OR ITS 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"

#if ENABLE(INDEXED_DATABASE)

#include "IDBBindingUtilities.h"

#include "ExceptionCode.h"
#include "IDBIndexInfo.h"
#include "IDBKey.h"
#include "IDBKeyData.h"
#include "IDBKeyPath.h"
#include "IDBValue.h"
#include "IndexKey.h"
#include "JSBlob.h"
#include "JSDOMBinding.h"
#include "JSDOMConvertDate.h"
#include "JSDOMConvertNullable.h"
#include "JSDOMExceptionHandling.h"
#include "JSFile.h"
#include "Logging.h"
#include "MessagePort.h"
#include "ScriptExecutionContext.h"
#include "SerializedScriptValue.h"
#include "SharedBuffer.h"
#include "ThreadSafeDataBuffer.h"
#include <JavaScriptCore/ArrayBuffer.h>
#include <JavaScriptCore/DateInstance.h>
#include <JavaScriptCore/ObjectConstructor.h>

namespace WebCore {
using namespace JSC;

static bool get(ExecState& exec, JSValue object, const String& keyPathElement, JSValue& result)
{
    if (object.isString() && keyPathElement == "length") {
        result = jsNumber(asString(object)->length());
        return true;
    }
    if (!object.isObject())
        return false;

    VM& vm = exec.vm();
    auto* obj = asObject(object);
    Identifier identifier = Identifier::fromString(vm, keyPathElement);
    if (obj->inherits<JSArray>(vm) && keyPathElement == "length") {
        result = obj->get(&exec, identifier);
        return true;
    }
    if (obj->inherits<JSBlob>(vm) && (keyPathElement == "size" || keyPathElement == "type")) {
        if (keyPathElement == "size") {
            result = jsNumber(jsCast<JSBlob*>(obj)->wrapped().size());
            return true;
        }
        if (keyPathElement == "type") {
            result = jsString(vm, jsCast<JSBlob*>(obj)->wrapped().type());
            return true;
        }
    }
    if (obj->inherits<JSFile>(vm)) {
        if (keyPathElement == "name") {
            result = jsString(vm, jsCast<JSFile*>(obj)->wrapped().name());
            return true;
        }
        if (keyPathElement == "lastModified") {
            result = jsNumber(jsCast<JSFile*>(obj)->wrapped().lastModified());
            return true;
        }
        if (keyPathElement == "lastModifiedDate") {
            result = jsDate(exec, jsCast<JSFile*>(obj)->wrapped().lastModified());
            return true;
        }
    }

    PropertyDescriptor descriptor;
    if (!obj->getOwnPropertyDescriptor(&exec, identifier, descriptor))
        return false;
    if (!descriptor.enumerable())
        return false;

    result = obj->get(&exec, identifier);
    return true;
}

static bool canSet(JSValue object, const String& keyPathElement)
{
    UNUSED_PARAM(keyPathElement);
    return object.isObject();
}

static bool set(ExecState& exec, JSValue& object, const String& keyPathElement, JSValue jsValue)
{
    if (!canSet(object, keyPathElement))
        return false;
    VM& vm = exec.vm();
    Identifier identifier = Identifier::fromString(vm, keyPathElement);
    asObject(object)->putDirect(vm, identifier, jsValue);
    return true;
}

JSValue toJS(ExecState& state, JSGlobalObject& globalObject, IDBKey* key)
{
    if (!key) {
        // This must be undefined, not null.
        // Spec: http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBKeyRange
        return jsUndefined();
    }

    VM& vm = state.vm();
    Locker<JSLock> locker(vm.apiLock());
    auto scope = DECLARE_THROW_SCOPE(vm);

    switch (key->type()) {
    case IndexedDB::KeyType::Array: {
        auto& inArray = key->array();
        unsigned size = inArray.size();
        auto outArray = constructEmptyArray(&state, 0, &globalObject, size);
        RETURN_IF_EXCEPTION(scope, JSValue());
        for (size_t i = 0; i < size; ++i) {
            outArray->putDirectIndex(&state, i, toJS(state, globalObject, inArray.at(i).get()));
            RETURN_IF_EXCEPTION(scope, JSValue());
        }
        return outArray;
    }
    case IndexedDB::KeyType::Binary: {
        auto* data = key->binary().data();
        if (!data) {
            ASSERT_NOT_REACHED();
            return jsNull();
        }

        auto arrayBuffer = ArrayBuffer::create(data->data(), data->size());
        Structure* structure = globalObject.arrayBufferStructure(arrayBuffer->sharingMode());
        if (!structure)
            return jsNull();

        return JSArrayBuffer::create(state.vm(), structure, WTFMove(arrayBuffer));
    }
    case IndexedDB::KeyType::String:
        return jsStringWithCache(&state, key->string());
    case IndexedDB::KeyType::Date:
        // FIXME: This should probably be toJS<IDLDate>(...) as per:
        // http://w3c.github.io/IndexedDB/#request-convert-a-key-to-a-value
        return toJS<IDLNullable<IDLDate>>(state, key->date());
    case IndexedDB::KeyType::Number:
        return jsNumber(key->number());
    case IndexedDB::KeyType::Min:
    case IndexedDB::KeyType::Max:
    case IndexedDB::KeyType::Invalid:
        ASSERT_NOT_REACHED();
        return jsUndefined();
    }

    ASSERT_NOT_REACHED();
    return jsUndefined();
}

static const size_t maximumDepth = 2000;

static RefPtr<IDBKey> createIDBKeyFromValue(ExecState& exec, JSValue value, Vector<JSArray*>& stack)
{
    VM& vm = exec.vm();
    if (value.isNumber() && !std::isnan(value.toNumber(&exec)))
        return IDBKey::createNumber(value.toNumber(&exec));

    if (value.isString())
        return IDBKey::createString(asString(value)->value(&exec));

    if (value.inherits<DateInstance>(vm)) {
        auto dateValue = valueToDate(exec, value);
        if (!std::isnan(dateValue))
            return IDBKey::createDate(dateValue);
    }

    if (value.isObject()) {
        JSObject* object = asObject(value);
        if (auto* array = jsDynamicCast<JSArray*>(vm, object)) {
            size_t length = array->length();

            if (stack.contains(array))
                return nullptr;

            if (stack.size() >= maximumDepth)
                return nullptr;

            stack.append(array);

            Vector<RefPtr<IDBKey>> subkeys;
            for (size_t i = 0; i < length; i++) {
                JSValue item = array->getIndex(&exec, i);
                RefPtr<IDBKey> subkey = createIDBKeyFromValue(exec, item, stack);
                if (!subkey)
                    subkeys.append(IDBKey::createInvalid());
                else
                    subkeys.append(subkey);
            }

            stack.removeLast();
            return IDBKey::createArray(subkeys);
        }

        if (auto* arrayBuffer = jsDynamicCast<JSArrayBuffer*>(vm, value))
            return IDBKey::createBinary(*arrayBuffer);

        if (auto* arrayBufferView = jsDynamicCast<JSArrayBufferView*>(vm, value))
            return IDBKey::createBinary(*arrayBufferView);
    }
    return nullptr;
}

static Ref<IDBKey> createIDBKeyFromValue(ExecState& exec, JSValue value)
{
    Vector<JSArray*> stack;
    RefPtr<IDBKey> key = createIDBKeyFromValue(exec, value, stack);
    if (key)
        return *key;
    return IDBKey::createInvalid();
}

static JSValue getNthValueOnKeyPath(ExecState& exec, JSValue rootValue, const Vector<String>& keyPathElements, size_t index)
{
    JSValue currentValue(rootValue);
    ASSERT(index <= keyPathElements.size());
    for (size_t i = 0; i < index; i++) {
        JSValue parentValue(currentValue);
        if (!get(exec, parentValue, keyPathElements[i], currentValue))
            return jsUndefined();
    }
    return currentValue;
}

static RefPtr<IDBKey> internalCreateIDBKeyFromScriptValueAndKeyPath(ExecState& exec, const JSValue& value, const String& keyPath)
{
    Vector<String> keyPathElements;
    IDBKeyPathParseError error;
    IDBParseKeyPath(keyPath, keyPathElements, error);
    ASSERT(error == IDBKeyPathParseError::None);

    JSValue jsValue = value;
    jsValue = getNthValueOnKeyPath(exec, jsValue, keyPathElements, keyPathElements.size());
    if (jsValue.isUndefined())
        return nullptr;
    return createIDBKeyFromValue(exec, jsValue);
}

static JSValue ensureNthValueOnKeyPath(ExecState& exec, JSValue rootValue, const Vector<String>& keyPathElements, size_t index)
{
    JSValue currentValue(rootValue);

    ASSERT(index <= keyPathElements.size());
    for (size_t i = 0; i < index; i++) {
        JSValue parentValue(currentValue);
        const String& keyPathElement = keyPathElements[i];
        if (!get(exec, parentValue, keyPathElement, currentValue)) {
            JSObject* object = constructEmptyObject(&exec);
            if (!set(exec, parentValue, keyPathElement, JSValue(object)))
                return jsUndefined();
            currentValue = JSValue(object);
        }
    }

    return currentValue;
}

static bool canInjectNthValueOnKeyPath(ExecState& exec, JSValue rootValue, const Vector<String>& keyPathElements, size_t index)
{
    if (!rootValue.isObject())
        return false;

    JSValue currentValue(rootValue);

    ASSERT(index <= keyPathElements.size());
    for (size_t i = 0; i <= index; ++i) {
        JSValue parentValue(currentValue);
        const String& keyPathElement = keyPathElements[i];
        if (!get(exec, parentValue, keyPathElement, currentValue))
            return canSet(parentValue, keyPathElement);
    }
    return true;
}

bool injectIDBKeyIntoScriptValue(ExecState& exec, const IDBKeyData& keyData, JSValue value, const IDBKeyPath& keyPath)
{
    LOG(IndexedDB, "injectIDBKeyIntoScriptValue");

    ASSERT(WTF::holds_alternative<String>(keyPath));

    Vector<String> keyPathElements;
    IDBKeyPathParseError error;
    IDBParseKeyPath(WTF::get<String>(keyPath), keyPathElements, error);
    ASSERT(error == IDBKeyPathParseError::None);

    if (keyPathElements.isEmpty())
        return false;

    JSValue parent = ensureNthValueOnKeyPath(exec, value, keyPathElements, keyPathElements.size() - 1);
    if (parent.isUndefined())
        return false;

    auto key = keyData.maybeCreateIDBKey();
    if (!key)
        return false;

    // Do not set if object already has the correct property value.
    JSValue existingKey;
    if (get(exec, parent, keyPathElements.last(), existingKey) && !key->compare(createIDBKeyFromValue(exec, existingKey)))
        return true;
    if (!set(exec, parent, keyPathElements.last(), toJS(exec, *exec.lexicalGlobalObject(), key.get())))
        return false;

    return true;
}


RefPtr<IDBKey> maybeCreateIDBKeyFromScriptValueAndKeyPath(ExecState& exec, const JSValue& value, const IDBKeyPath& keyPath)
{
    if (WTF::holds_alternative<Vector<String>>(keyPath)) {
        auto& array = WTF::get<Vector<String>>(keyPath);
        Vector<RefPtr<IDBKey>> result;
        result.reserveInitialCapacity(array.size());
        for (auto& string : array) {
            RefPtr<IDBKey> key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, string);
            if (!key)
                return nullptr;
            result.uncheckedAppend(WTFMove(key));
        }
        return IDBKey::createArray(WTFMove(result));
    }

    return internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, WTF::get<String>(keyPath));
}

bool canInjectIDBKeyIntoScriptValue(ExecState& exec, const JSValue& scriptValue, const IDBKeyPath& keyPath)
{
    LOG(StorageAPI, "canInjectIDBKeyIntoScriptValue");

    ASSERT(WTF::holds_alternative<String>(keyPath));
    Vector<String> keyPathElements;
    IDBKeyPathParseError error;
    IDBParseKeyPath(WTF::get<String>(keyPath), keyPathElements, error);
    ASSERT(error == IDBKeyPathParseError::None);

    if (!keyPathElements.size())
        return false;

    return canInjectNthValueOnKeyPath(exec, scriptValue, keyPathElements, keyPathElements.size() - 1);
}

static JSValue deserializeIDBValueToJSValue(ExecState& state, JSC::JSGlobalObject& globalObject, const IDBValue& value)
{
    // FIXME: I think it's peculiar to use undefined to mean "null data" and null to mean "empty data".
    // But I am not changing this at the moment because at least some callers are specifically checking isUndefined.

    if (!value.data().data())
        return jsUndefined();

    auto& data = *value.data().data();
    if (data.isEmpty())
        return jsNull();

    auto serializedValue = SerializedScriptValue::createFromWireBytes(Vector<uint8_t>(data));

    state.vm().apiLock().lock();
    Vector<RefPtr<MessagePort>> messagePorts;
    JSValue result = serializedValue->deserialize(state, &globalObject, messagePorts, value.blobURLs(), value.blobFilePaths(), SerializationErrorMode::NonThrowing);
    state.vm().apiLock().unlock();

    return result;
}

JSValue deserializeIDBValueToJSValue(ExecState& state, const IDBValue& value)
{
    return deserializeIDBValueToJSValue(state, *state.lexicalGlobalObject(), value);
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, const IDBValue& value)
{
    ASSERT(state);
    return deserializeIDBValueToJSValue(*state, *globalObject, value);
}

Ref<IDBKey> scriptValueToIDBKey(ExecState& exec, const JSValue& scriptValue)
{
    return createIDBKeyFromValue(exec, scriptValue);
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, const IDBKeyData& keyData)
{
    ASSERT(state);
    ASSERT(globalObject);

    return toJS(*state, *globalObject, keyData.maybeCreateIDBKey().get());
}

static Vector<IDBKeyData> createKeyPathArray(ExecState& exec, JSValue value, const IDBIndexInfo& info, Optional<IDBKeyPath> objectStoreKeyPath, const IDBKeyData& objectStoreKey)
{
    auto visitor = WTF::makeVisitor([&](const String& string) -> Vector<IDBKeyData> {
        // Value doesn't contain auto-generated key, so we need to manually add key if it is possibly auto-generated.
        if (objectStoreKeyPath && WTF::holds_alternative<String>(objectStoreKeyPath.value()) && IDBKeyPath(string) == objectStoreKeyPath.value())
            return { objectStoreKey };

        auto idbKey = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, string);
        if (!idbKey)
            return { };

        Vector<IDBKeyData> keys;
        if (info.multiEntry() && idbKey->type() == IndexedDB::Array) {
            for (auto& key : idbKey->array())
                keys.append(key.get());
        } else
            keys.append(idbKey.get());
        return keys;
    }, [&](const Vector<String>& vector) -> Vector<IDBKeyData> {
        Vector<IDBKeyData> keys;
        for (auto& entry : vector) {
            if (objectStoreKeyPath && WTF::holds_alternative<String>(objectStoreKeyPath.value()) && IDBKeyPath(entry) == objectStoreKeyPath.value())
                keys.append(objectStoreKey);
            else {
                auto key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, entry);
                if (!key || !key->isValid())
                    return { };
                keys.append(key.get());
            }
        }
        return keys;
    });

    return WTF::visit(visitor, info.keyPath());
}

void generateIndexKeyForValue(ExecState& exec, const IDBIndexInfo& info, JSValue value, IndexKey& outKey, const Optional<IDBKeyPath>& objectStoreKeyPath, const IDBKeyData& objectStoreKey)
{
    auto keyDatas = createKeyPathArray(exec, value, info, objectStoreKeyPath, objectStoreKey);
    if (keyDatas.isEmpty())
        return;

    outKey = IndexKey(WTFMove(keyDatas));
}

Optional<JSC::JSValue> deserializeIDBValueWithKeyInjection(ExecState& state, const IDBValue& value, const IDBKeyData& key, const Optional<IDBKeyPath>& keyPath)
{
    auto jsValue = deserializeIDBValueToJSValue(state, value);
    if (jsValue.isUndefined() || !keyPath || !WTF::holds_alternative<String>(keyPath.value()) || !isIDBKeyPathValid(keyPath.value()))
        return jsValue;

    JSLockHolder locker(state.vm());
    if (!injectIDBKeyIntoScriptValue(state, key, jsValue, keyPath.value())) {
        auto throwScope = DECLARE_THROW_SCOPE(state.vm());
        propagateException(state, throwScope, Exception(UnknownError, "Cannot inject key into script value"_s));
        return WTF::nullopt;
    }

    return jsValue;
}

} // namespace WebCore

#endif // ENABLE(INDEXED_DATABASE)
