/*
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2012 Ericsson AB. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
*     * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*     * 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.
*     * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
* OWNER 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.
*/

#ifndef V8Binding_h
#define V8Binding_h

#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/V8BindingMacros.h"
#include "bindings/v8/V8PerIsolateData.h"
#include "bindings/v8/V8StringResource.h"
#include "bindings/v8/V8ThrowException.h"
#include "bindings/v8/V8ValueCache.h"
#include "wtf/MathExtras.h"
#include "wtf/text/AtomicString.h"
#include <v8.h>

namespace WebCore {

    class DOMStringList;
    class DOMWindow;
    class Document;
    class Frame;
    class NodeFilter;
    class ScriptExecutionContext;
    class XPathNSResolver;

    const int kMaxRecursionDepth = 22;

    // Schedule a DOM exception to be thrown, if the exception code is different
    // from zero.
    v8::Handle<v8::Value> setDOMException(int, v8::Isolate*);

    // Schedule a JavaScript error to be thrown.
    v8::Handle<v8::Value> throwError(V8ErrorType, const char*, v8::Isolate*);

    // Schedule a JavaScript error to be thrown.
    v8::Handle<v8::Value> throwError(v8::Handle<v8::Value>, v8::Isolate*);

    // A helper for throwing JavaScript TypeError.
    v8::Handle<v8::Value> throwTypeError(const char*, v8::Isolate*);

    // A helper for throwing JavaScript TypeError for not enough arguments.
    v8::Handle<v8::Value> throwNotEnoughArgumentsError(v8::Isolate*);

    v8::ArrayBuffer::Allocator* v8ArrayBufferAllocator();

    inline v8::Handle<v8::Value> argumentOrNull(const v8::FunctionCallbackInfo<v8::Value>& args, int index)
    {
        return index >= args.Length() ? v8::Local<v8::Value>() : args[index];
    }

    // Since v8::Null(isolate) crashes if we pass a null isolate,
    // we need to use v8NullWithCheck(isolate) if an isolate can be null.
    //
    // FIXME: Remove all null isolates from V8 bindings, and remove v8NullWithCheck(isolate).
    inline v8::Handle<v8::Value> v8NullWithCheck(v8::Isolate* isolate)
    {
        return v8::Handle<v8::Value>(isolate ? v8::Null(isolate) : v8::Null());
    }

    template<typename CallbackInfo, typename V>
    inline void v8SetReturnValue(const CallbackInfo& args, V v)
    {
        args.GetReturnValue().Set(v);
    }

    template<typename CallbackInfo>
    inline void v8SetReturnValueBool(const CallbackInfo& args, bool v)
    {
        args.GetReturnValue().Set(v);
    }

    template<typename CallbackInfo>
    inline void v8SetReturnValueInt(const CallbackInfo& args, int v)
    {
        args.GetReturnValue().Set(v);
    }

    template<typename CallbackInfo>
    inline void v8SetReturnValueUnsigned(const CallbackInfo& args, unsigned v)
    {
        // FIXME: this is temporary workaround to a v8 bug
        if (V8_LIKELY((v & (1 << 31)) == 0)) {
            args.GetReturnValue().Set(static_cast<int32_t>(v));
            return;
        }
        args.GetReturnValue().Set(v8::Integer::NewFromUnsigned(v, args.GetReturnValue().GetIsolate()));
    }

    template<typename CallbackInfo>
    inline void v8SetReturnValueNull(const CallbackInfo& args)
    {
        args.GetReturnValue().SetNull();
    }

    enum TreatNullStringAs {
        NullStringAsEmpty,
        NullStringAsNull,
        NullStringAsUndefined,
    };

    template <class CallbackInfo>
    inline void v8SetReturnValueString(const CallbackInfo& info, const String& string, v8::Isolate* isolate, TreatNullStringAs treatNullStringAs = NullStringAsEmpty)
    {
        if (string.isNull()) {
            switch (treatNullStringAs) {
            case NullStringAsEmpty:
                v8SetReturnValue(info, v8::String::Empty(isolate));
                break;
            case NullStringAsNull:
                v8SetReturnValueNull(info);
                break;
            case NullStringAsUndefined:
                v8SetReturnValue(info, v8::Undefined(isolate));
                break;
            }
            return;
        }
        V8PerIsolateData::from(isolate)->stringCache()->setReturnValueFromString(info, string.impl(), isolate);
    }

    // Convert v8 types to a WTF::String. If the V8 string is not already
    // an external string then it is transformed into an external string at this
    // point to avoid repeated conversions.
    //
    // FIXME: Replace all the call sites with V8TRYCATCH_FOR_V8STRINGRESOURCE().
    // Using this method will lead to a wrong behavior, because you cannot stop the
    // execution when an exception is thrown inside stringResource.prepare().
    inline String toWebCoreString(v8::Handle<v8::Value> value)
    {
        V8StringResource<> stringResource(value);
        if (!stringResource.prepare())
            return String();
        return stringResource;
    }

    // FIXME: See the above comment.
    inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
    {
        V8StringResource<WithNullCheck> stringResource(value);
        if (!stringResource.prepare())
            return String();
        return stringResource;
    }

    // FIXME: See the above comment.
    inline String toWebCoreStringWithUndefinedOrNullCheck(v8::Handle<v8::Value> value)
    {
        V8StringResource<WithUndefinedOrNullCheck> stringResource(value);
        if (!stringResource.prepare())
            return String();
        return stringResource;
    }

    // FIXME: See the above comment.
    inline AtomicString toWebCoreAtomicString(v8::Handle<v8::Value> value)
    {
        V8StringResource<> stringResource(value);
        if (!stringResource.prepare())
            return AtomicString();
        return stringResource;
    }

    // FIXME: See the above comment.
    inline AtomicString toWebCoreAtomicStringWithNullCheck(v8::Handle<v8::Value> value)
    {
        V8StringResource<WithNullCheck> stringResource(value);
        if (!stringResource.prepare())
            return AtomicString();
        return stringResource;
    }

    // Convert a string to a V8 string.
    // Return a V8 external string that shares the underlying buffer with the given
    // WebCore string. The reference counting mechanism is used to keep the
    // underlying buffer alive while the string is still live in the V8 engine.
    inline v8::Handle<v8::String> v8String(const String& string, v8::Isolate* isolate)
    {
        if (string.isNull())
            return v8::String::Empty(isolate);
        return V8PerIsolateData::from(isolate)->stringCache()->v8ExternalString(string.impl(), isolate);
    }

    inline v8::Handle<v8::Value> v8Undefined()
    {
        return v8::Handle<v8::Value>();
    }

    template <class T>
    struct V8ValueTraits {
        static inline v8::Handle<v8::Value> arrayV8Value(const T& value, v8::Isolate* isolate)
        {
            return toV8(WTF::getPtr(value), v8::Handle<v8::Object>(), isolate);
        }
    };

    template<>
    struct V8ValueTraits<String> {
        static inline v8::Handle<v8::Value> arrayV8Value(const String& value, v8::Isolate* isolate)
        {
            return v8String(value, isolate);
        }
    };

    template<>
    struct V8ValueTraits<unsigned long> {
        static inline v8::Handle<v8::Value> arrayV8Value(const unsigned long& value, v8::Isolate* isolate)
        {
            return v8::Integer::NewFromUnsigned(value, isolate);
        }
    };

    template<>
    struct V8ValueTraits<float> {
        static inline v8::Handle<v8::Value> arrayV8Value(const float& value, v8::Isolate*)
        {
            return v8::Number::New(value);
        }
    };

    template<>
    struct V8ValueTraits<double> {
        static inline v8::Handle<v8::Value> arrayV8Value(const double& value, v8::Isolate*)
        {
            return v8::Number::New(value);
        }
    };

    template<typename T, size_t inlineCapacity>
    v8::Handle<v8::Value> v8Array(const Vector<T, inlineCapacity>& iterator, v8::Isolate* isolate)
    {
        v8::Local<v8::Array> result = v8::Array::New(iterator.size());
        int index = 0;
        typename Vector<T, inlineCapacity>::const_iterator end = iterator.end();
        typedef V8ValueTraits<T> TraitsType;
        for (typename Vector<T, inlineCapacity>::const_iterator iter = iterator.begin(); iter != end; ++iter)
            result->Set(v8::Integer::New(index++, isolate), TraitsType::arrayV8Value(*iter, isolate));
        return result;
    }

    v8::Handle<v8::Value> v8Array(PassRefPtr<DOMStringList>, v8::Isolate*);

    // Conversion flags, used in toIntXX/toUIntXX.
    enum IntegerConversionConfiguration {
        NormalConversion,
        EnforceRange,
        // FIXME: Implement Clamp
    };

    // Convert a value to a 8-bit signed integer. The conversion fails if the
    // value cannot be converted to a number or the range violated per WebIDL:
    // http://www.w3.org/TR/WebIDL/#es-byte
    int8_t toInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    inline int8_t toInt8(v8::Handle<v8::Value> value, bool& ok) { return toInt8(value, NormalConversion, ok); }

    // Convert a value to a 8-bit integer assuming the conversion cannot fail.
    inline int8_t toInt8(v8::Handle<v8::Value> value)
    {
        bool ok;
        return toInt8(value, NormalConversion, ok);
    }

    // Convert a value to a 8-bit unsigned integer. The conversion fails if the
    // value cannot be converted to a number or the range violated per WebIDL:
    // http://www.w3.org/TR/WebIDL/#es-octet
    uint8_t toUInt8(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    inline uint8_t toUInt8(v8::Handle<v8::Value> value, bool& ok) { return toUInt8(value, NormalConversion, ok); }

    // Convert a value to a 8-bit unsigned integer assuming the conversion cannot fail.
    inline uint8_t toUInt8(v8::Handle<v8::Value> value)
    {
        bool ok;
        return toUInt8(value, NormalConversion, ok);
    }

    // Convert a value to a 32-bit signed integer. The conversion fails if the
    // value cannot be converted to a number or the range violated per WebIDL:
    // http://www.w3.org/TR/WebIDL/#es-long
    int32_t toInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    inline int32_t toInt32(v8::Handle<v8::Value> value, bool& ok) { return toInt32(value, NormalConversion, ok); }

    // Convert a value to a 32-bit integer assuming the conversion cannot fail.
    inline int32_t toInt32(v8::Handle<v8::Value> value)
    {
        bool ok;
        return toInt32(value, NormalConversion, ok);
    }

    // Convert a value to a 32-bit unsigned integer. The conversion fails if the
    // value cannot be converted to a number or the range violated per WebIDL:
    // http://www.w3.org/TR/WebIDL/#es-unsigned-long
    uint32_t toUInt32(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);
    inline uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok) { return toUInt32(value, NormalConversion, ok); }

    // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
    inline uint32_t toUInt32(v8::Handle<v8::Value> value)
    {
        bool ok;
        return toUInt32(value, NormalConversion, ok);
    }

    // Convert a value to a 64-bit signed integer. The conversion fails if the
    // value cannot be converted to a number or the range violated per WebIDL:
    // http://www.w3.org/TR/WebIDL/#es-long-long
    int64_t toInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);

    // Convert a value to a 64-bit integer assuming the conversion cannot fail.
    inline int64_t toInt64(v8::Handle<v8::Value> value)
    {
        bool ok;
        return toInt64(value, NormalConversion, ok);
    }

    // Convert a value to a 64-bit unsigned integer. The conversion fails if the
    // value cannot be converted to a number or the range violated per WebIDL:
    // http://www.w3.org/TR/WebIDL/#es-unsigned-long-long
    uint64_t toUInt64(v8::Handle<v8::Value>, IntegerConversionConfiguration, bool& ok);

    // Convert a value to a 64-bit unsigned integer assuming the conversion cannot fail.
    inline uint64_t toUInt64(v8::Handle<v8::Value> value)
    {
        bool ok;
        return toUInt64(value, NormalConversion, ok);
    }

    inline float toFloat(v8::Local<v8::Value> value)
    {
        return static_cast<float>(value->NumberValue());
    }

    WrapperWorldType worldType(v8::Isolate*);
    WrapperWorldType worldTypeInMainThread(v8::Isolate*);

    DOMWrapperWorld* isolatedWorldForIsolate(v8::Isolate*);

    template<class T> struct NativeValueTraits;

    template<>
    struct NativeValueTraits<String> {
        static inline String nativeValue(const v8::Handle<v8::Value>& value)
        {
            return toWebCoreString(value);
        }
    };

    template<>
    struct NativeValueTraits<unsigned> {
        static inline unsigned nativeValue(const v8::Handle<v8::Value>& value)
        {
            return toUInt32(value);
        }
    };

    template<>
    struct NativeValueTraits<float> {
        static inline float nativeValue(const v8::Handle<v8::Value>& value)
        {
            return static_cast<float>(value->NumberValue());
        }
    };

    template<>
    struct NativeValueTraits<double> {
        static inline double nativeValue(const v8::Handle<v8::Value>& value)
        {
            return static_cast<double>(value->NumberValue());
        }
    };

    template <class T, class V8T>
    Vector<RefPtr<T> > toRefPtrNativeArray(v8::Handle<v8::Value> value, v8::Isolate* isolate)
    {
        if (!value->IsArray())
            return Vector<RefPtr<T> >();

        Vector<RefPtr<T> > result;
        v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(value));
        v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(v8Value);
        size_t length = array->Length();
        for (size_t i = 0; i < length; ++i) {
            v8::Handle<v8::Value> element = array->Get(i);

            if (V8T::HasInstance(element, isolate, worldType(isolate))) {
                v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(element);
                result.append(V8T::toNative(object));
            } else {
                throwTypeError("Invalid Array element type", isolate);
                return Vector<RefPtr<T> >();
            }
        }
        return result;
    }

    template <class T>
    Vector<T> toNativeArray(v8::Handle<v8::Value> value)
    {
        if (!value->IsArray())
            return Vector<T>();

        Vector<T> result;
        typedef NativeValueTraits<T> TraitsType;
        v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(value));
        v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(v8Value);
        size_t length = array->Length();
        for (size_t i = 0; i < length; ++i)
            result.append(TraitsType::nativeValue(array->Get(i)));
        return result;
    }

    template <class T>
    Vector<T> toNativeArguments(const v8::FunctionCallbackInfo<v8::Value>& args, int startIndex)
    {
        ASSERT(startIndex <= args.Length());
        Vector<T> result;
        typedef NativeValueTraits<T> TraitsType;
        int length = args.Length();
        for (int i = startIndex; i < length; ++i)
            result.append(TraitsType::nativeValue(args[i]));
        return result;
    }

    Vector<v8::Handle<v8::Value> > toVectorOfArguments(const v8::FunctionCallbackInfo<v8::Value>& args);

    // Validates that the passed object is a sequence type per WebIDL spec
    // http://www.w3.org/TR/2012/WD-WebIDL-20120207/#es-sequence
    inline v8::Handle<v8::Value> toV8Sequence(v8::Handle<v8::Value> value, uint32_t& length, v8::Isolate* isolate)
    {
        if (!value->IsObject()) {
            throwTypeError(0, isolate);
            return v8Undefined();
        }

        v8::Local<v8::Value> v8Value(v8::Local<v8::Value>::New(value));
        v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(v8Value);

        V8TRYCATCH(v8::Local<v8::Value>, lengthValue, object->Get(v8::String::NewSymbol("length")));

        if (lengthValue->IsUndefined() || lengthValue->IsNull()) {
            throwTypeError(0, isolate);
            return v8Undefined();
        }

        V8TRYCATCH(uint32_t, sequenceLength, lengthValue->Int32Value());
        length = sequenceLength;

        return v8Value;
    }

    PassRefPtr<NodeFilter> toNodeFilter(v8::Handle<v8::Value>);

    inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
    {
        return value->IsNull() || value->IsUndefined();
    }

    // Returns true if the provided object is to be considered a 'host object', as used in the
    // HTML5 structured clone algorithm.
    inline bool isHostObject(v8::Handle<v8::Object> object)
    {
        // If the object has any internal fields, then we won't be able to serialize or deserialize
        // them; conveniently, this is also a quick way to detect DOM wrapper objects, because
        // the mechanism for these relies on data stored in these fields. We should
        // catch external array data as a special case.
        return object->InternalFieldCount() || object->HasIndexedPropertiesInExternalArrayData();
    }

    inline v8::Handle<v8::Boolean> v8Boolean(bool value)
    {
        return value ? v8::True() : v8::False();
    }

    inline v8::Handle<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate)
    {
        return value ? v8::True(isolate) : v8::False(isolate);
    }

    // Since v8Boolean(value, isolate) crashes if we pass a null isolate,
    // we need to use v8BooleanWithCheck(value, isolate) if an isolate can be null.
    //
    // FIXME: Remove all null isolates from V8 bindings, and remove v8BooleanWithCheck(value, isolate).
    inline v8::Handle<v8::Boolean> v8BooleanWithCheck(bool value, v8::Isolate* isolate)
    {
        return isolate ? v8Boolean(value, isolate) : v8Boolean(value);
    }

    inline double toWebCoreDate(v8::Handle<v8::Value> object)
    {
        return (object->IsDate() || object->IsNumber()) ? object->NumberValue() : std::numeric_limits<double>::quiet_NaN();
    }

    inline v8::Handle<v8::Value> v8DateOrNull(double value, v8::Isolate* isolate)
    {
        ASSERT(isolate);
        return std::isfinite(value) ? v8::Date::New(value) : v8NullWithCheck(isolate);
    }

    v8::Handle<v8::FunctionTemplate> createRawTemplate(v8::Isolate*);

    PassRefPtr<DOMStringList> toDOMStringList(v8::Handle<v8::Value>, v8::Isolate*);
    PassRefPtr<XPathNSResolver> toXPathNSResolver(v8::Handle<v8::Value>, v8::Isolate*);

    v8::Handle<v8::Object> toInnerGlobalObject(v8::Handle<v8::Context>);
    DOMWindow* toDOMWindow(v8::Handle<v8::Context>);
    ScriptExecutionContext* toScriptExecutionContext(v8::Handle<v8::Context>);

    DOMWindow* activeDOMWindow();
    DOMWindow* firstDOMWindow();
    Document* currentDocument();

    // Returns the context associated with a ScriptExecutionContext.
    v8::Local<v8::Context> toV8Context(ScriptExecutionContext*, DOMWrapperWorld*);

    // Returns the frame object of the window object associated with
    // a context, if the window is currently being displayed in the Frame.
    Frame* toFrameIfNotDetached(v8::Handle<v8::Context>);

    inline DOMWrapperWorld* isolatedWorldForEnteredContext()
    {
        v8::Handle<v8::Context> context = v8::Context::GetEntered();
        if (context.IsEmpty())
            return 0;
        return DOMWrapperWorld::isolatedWorld(context);
    }

    // FIXME: This will be soon embedded in the generated code.
    template<class Collection> static void indexedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
    {
        Collection* collection = reinterpret_cast<Collection*>(info.Holder()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex));
        int length = collection->length();
        v8::Handle<v8::Array> properties = v8::Array::New(length);
        for (int i = 0; i < length; ++i) {
            // FIXME: Do we need to check that the item function returns a non-null value for this index?
            v8::Handle<v8::Integer> integer = v8::Integer::New(i, info.GetIsolate());
            properties->Set(integer, integer);
        }
        v8SetReturnValue(info, properties);
    }

    // If the current context causes out of memory, JavaScript setting
    // is disabled and it returns true.
    bool handleOutOfMemory();
    // FIXME: This should receive an Isolate.
    v8::Local<v8::Value> handleMaxRecursionDepthExceeded();

    void crashIfV8IsDead();

    template <class T>
    v8::Handle<T> unsafeHandleFromRawValue(const T* value)
    {
        const v8::Handle<T>* handle = reinterpret_cast<const v8::Handle<T>*>(&value);
        return *handle;
    }

    // Attaches |environment| to |function| and returns it.
    inline v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle<v8::Value> environment)
    {
        return v8::FunctionTemplate::New(function, environment)->GetFunction();
    }

} // namespace WebCore

#endif // V8Binding_h
