/*
 * Copyright (C) 2004-2019 Apple Inc.  All rights reserved.
 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
 *
 * 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"

#if ENABLE(NETSCAPE_PLUGIN_API)

#include "c_utility.h"

#include "CRuntimeObject.h"
#include "DOMWindow.h"
#include "JSDOMBinding.h"
#include "JSDOMWindow.h"
#include "NP_jsobject.h"
#include "c_instance.h"
#include "npruntime_impl.h"
#include "npruntime_priv.h"
#include "runtime_object.h"
#include "runtime_root.h"
#include <JavaScriptCore/JSGlobalObject.h>
#include <JavaScriptCore/JSLock.h>
#include <wtf/Assertions.h>
#include <wtf/text/WTFString.h>

namespace JSC { namespace Bindings {

static String convertUTF8ToUTF16WithLatin1Fallback(const NPUTF8* UTF8Chars, int UTF8Length)
{
    ASSERT(UTF8Chars || UTF8Length == 0);
    
    if (UTF8Length == -1)
        UTF8Length = static_cast<int>(strlen(UTF8Chars));

    String result = String::fromUTF8(UTF8Chars, UTF8Length);
    
    // If we got back a null string indicating an unsuccessful conversion, fall back to latin 1.
    // Some plugins return invalid UTF-8 in NPVariantType_String, see <http://bugs.webkit.org/show_bug.cgi?id=5163>
    // There is no "bad data" for latin1. It is unlikely that the plugin was really sending text in this encoding,
    // but it should have used UTF-8, and now we are simply avoiding a crash.
    if (result.isNull())
        result = String(UTF8Chars, UTF8Length);
    
    return result;
}

// Variant value must be released with NPReleaseVariantValue()
void convertValueToNPVariant(JSGlobalObject* exec, JSValue value, NPVariant* result)
{
    JSLockHolder lock(exec);
    VM& vm = exec->vm();
    
    VOID_TO_NPVARIANT(*result);

    if (value.isString()) {
        String ustring = value.toWTFString(exec);
        CString cstring = ustring.utf8();
        NPString string = { (const NPUTF8*)cstring.data(), static_cast<uint32_t>(cstring.length()) };
        NPN_InitializeVariantWithStringCopy(result, &string);
    } else if (value.isNumber()) {
        DOUBLE_TO_NPVARIANT(value.toNumber(exec), *result);
    } else if (value.isBoolean()) {
        BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), *result);
    } else if (value.isNull()) {
        NULL_TO_NPVARIANT(*result);
    } else if (value.isObject()) {
        JSObject* object = asObject(value);
        if (object->classInfo(vm) == CRuntimeObject::info()) {
            CRuntimeObject* runtimeObject = static_cast<CRuntimeObject*>(object);
            CInstance* instance = runtimeObject->getInternalCInstance();
            if (instance) {
                NPObject* obj = instance->getObject();
                _NPN_RetainObject(obj);
                OBJECT_TO_NPVARIANT(obj, *result);
            }
        } else {
            JSGlobalObject* globalObject = vm.deprecatedVMEntryGlobalObject(exec);

            RootObject* rootObject = findRootObject(globalObject);
            if (rootObject) {
                NPObject* npObject = _NPN_CreateScriptObject(0, object, rootObject);
                OBJECT_TO_NPVARIANT(npObject, *result);
            }
        }
    }
}

JSValue convertNPVariantToValue(JSGlobalObject* exec, const NPVariant* variant, RootObject* rootObject)
{
    JSLockHolder lock(exec);
    
    NPVariantType type = variant->type;

    if (type == NPVariantType_Bool)
        return jsBoolean(NPVARIANT_TO_BOOLEAN(*variant));
    if (type == NPVariantType_Null)
        return jsNull();
    if (type == NPVariantType_Void)
        return jsUndefined();
    if (type == NPVariantType_Int32)
        return jsNumber(NPVARIANT_TO_INT32(*variant));
    if (type == NPVariantType_Double)
        return jsNumber(NPVARIANT_TO_DOUBLE(*variant));
    if (type == NPVariantType_String)
        return jsStringWithCache(exec, convertNPStringToUTF16(&variant->value.stringValue));
    if (type == NPVariantType_Object) {
        NPObject* obj = variant->value.objectValue;
        
        if (obj->_class == NPScriptObjectClass)
            // Get JSObject from NP_JavaScriptObject.
            return ((JavaScriptObject*)obj)->imp;

        // Wrap NPObject in a CInstance.
        return CInstance::create(obj, rootObject)->createRuntimeObject(exec);
    }
    
    return jsUndefined();
}

String convertNPStringToUTF16(const NPString* string)
{
    return String::fromUTF8WithLatin1Fallback(string->UTF8Characters, string->UTF8Length);
}

Identifier identifierFromNPIdentifier(JSGlobalObject* exec, const NPUTF8* name)
{
    VM& vm = exec->vm();
    return Identifier::fromString(vm, convertUTF8ToUTF16WithLatin1Fallback(name, -1));
}

} }

#endif // ENABLE(NETSCAPE_PLUGIN_API)
