/*
 * Copyright (C) 2005 Apple Computer, 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. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 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"
#include "JavaScriptGlue.h"
#include "JSUtils.h"
#include "JSBase.h"
#include "JSObject.h"
#include "JSRun.h"
#include <JavaScriptCore/Completion.h>
#include <JavaScriptCore/InitializeThreading.h>

static CFTypeRef sJSCFNullRef = 0;

static void CFJSObjectDispose(void *data);
static JSObjectRef CFJSObjectCopyProperty(void *data, CFStringRef propertyName);
static void CFJSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue);
static CFTypeRef CFJSObjectCopyCFValue(void *data);
static UInt8 CFJSObjectEqual(void *data1, void *data2);
static CFArrayRef CFJSObjectCopyPropertyNames(void *data);

void *JSCFRetain(CFAllocatorRef allocator, const void *value);
void JSCFRelease(CFAllocatorRef allocator, const void *value);


void JSSetCFNull(CFTypeRef nullRef)
{
    ReleaseCFType(sJSCFNullRef);
    sJSCFNullRef = RetainCFType(nullRef);
}

CFTypeRef JSGetCFNull(void)
{
    return sJSCFNullRef;
}

/*
    JSRetain
*/
JSTypeRef JSRetain(JSTypeRef ref)
{
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        ptr->Retain();
    }
    return ref;
}

/*
    JSRelease
*/
void JSRelease(JSTypeRef ref)
{
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        ptr->Release();
    }
}

/*
    JSCopyDescription
*/
CFStringRef JSCopyDescription(JSTypeRef ref)
{
    CFStringRef result = 0;
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        ptr->CopyDescription();
    }
    return result;
}

/*
    JSEqual
*/
UInt8 JSEqual(JSTypeRef ref1, JSTypeRef ref2)
{
    UInt8 result = false;
    if (ref1 && ref2)
    {
        JSBase* ptr = (JSBase*)ref1;
        result = ptr->Equal((JSBase*)ref2);
    }
    return result;
}


/*
    JSGetTypeID
*/
JSTypeID JSGetTypeID(JSTypeRef ref)
{
    JSTypeID result = kJSInvalidTypeID;
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        result = ptr->GetTypeID();
    }
    return result;
}


/*
    JSGetRetainCount
*/
CFIndex JSGetRetainCount(JSTypeRef ref)
{
    CFIndex result = -1;
    if (ref)
    {
        JSBase* ptr = (JSBase*)ref;
        result = ptr->RetainCount();
    }
    return result;
}



/*
    JSObjectCreate
*/
JSObjectRef JSObjectCreate(void *data, JSObjectCallBacksPtr callBacks)
{
    JSObjectRef result = JSObjectCreateInternal(data, callBacks, 0, kJSUserObjectDataTypeUnknown);
    return result;
}

/*
    JSObjectCreateInternal
*/
JSObjectRef JSObjectCreateInternal(void *data, JSObjectCallBacksPtr callBacks, JSObjectMarkProcPtr markProc, int type)
{
    JSObjectRef result = 0;
    JSUserObject* ptr = new JSUserObject(callBacks, markProc, data, type);
    result = (JSObjectRef)ptr;
    return result;
}

/*
    JSObjectCopyCFValue
*/
CFTypeRef JSObjectCopyCFValue(JSObjectRef ref)
{
    CFTypeRef result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = ptr->CopyCFValue();
    }
    return result;
}

/*
    JSObjectGetData
*/
void *JSObjectGetData(JSObjectRef ref)
{
    void *result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = ptr->GetData();
    }
    return result;
}


/*
    JSObjectCopyProperty
*/
JSObjectRef JSObjectCopyProperty(JSObjectRef ref, CFStringRef propertyName)
{
    JSObjectRef result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = (JSObjectRef)ptr->CopyProperty(propertyName);
    }
    return result;
}


/*
    JSObjectSetProperty
*/
void JSObjectSetProperty(JSObjectRef ref, CFStringRef propertyName, JSObjectRef value)
{
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        ptr->SetProperty(propertyName, (JSUserObject*)value);
    }
}


/*
    JSObjectCallFunction
*/
JSObjectRef JSObjectCallFunction(JSObjectRef ref, JSObjectRef thisObj, CFArrayRef args)
{
    JSObjectRef result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = (JSObjectRef)ptr->CallFunction((JSUserObject*)thisObj, args);
    }
    return result;
}


/*
    JSRunCreate
*/
JSRunRef JSRunCreate(CFStringRef jsSource, JSFlags inFlags)
{
    initializeThreading();

    JSRunRef result = 0;
    if (jsSource)
    {
        JSGlueAPIEntry entry;
        result = (JSRunRef) new JSRun(jsSource, inFlags);
    }
    return result;
}

/*
    JSRunCopySource
*/
CFStringRef JSRunCopySource(JSRunRef ref)
{
    CFStringRef result = 0;
    JSRun* ptr = (JSRun*)ref;
    if (ptr)
    {
        result = UStringToCFString(ptr->GetSource());
    }
    return result;
}


/*
    JSRunCopyGlobalObject
*/
JSObjectRef JSRunCopyGlobalObject(JSRunRef ref)
{
    JSObjectRef result = 0;
    JSRun* ptr = (JSRun*)ref;
    if (ptr)
    {
        JSGlobalObject* globalObject = ptr->GlobalObject();
        result = (JSObjectRef)KJSValueToJSObject(globalObject, globalObject->globalExec());
    }
    return result;
}

/*
    JSRunEvaluate
*/
JSObjectRef JSRunEvaluate(JSRunRef ref)
{
    JSObjectRef result = 0;
    JSRun* ptr = (JSRun*)ref;
    if (ptr)
    {
        JSGlueAPIEntry entry;
        Completion completion = ptr->Evaluate();
        if (completion.isValueCompletion())
        {
            result = (JSObjectRef)KJSValueToJSObject(completion.value(), ptr->GlobalObject()->globalExec());
        }

        if (completion.complType() == Throw)
        {
            JSFlags flags = ptr->Flags();
            if (flags & kJSFlagDebug)
            {
                CFTypeRef error = JSObjectCopyCFValue(result);
                if (error)
                {
                    CFShow(error);
                    CFRelease(error);
                }
            }
        }
    }
    return result;
}

/*
    JSRunCheckSyntax
    Return true if no syntax error
*/
bool JSRunCheckSyntax(JSRunRef ref)
{
    bool result = false;
    JSRun* ptr = (JSRun*)ref;
    if (ptr)
    {
            JSGlueAPIEntry entry;
            result = ptr->CheckSyntax();
    }
    return result;
}

/*
    JSCollect - trigger garbage collection
*/
void JSCollect()
{
    initializeThreading();

    JSGlueAPIEntry entry;
    Heap* heap = getThreadGlobalExecState()->heap();
    if (!heap->isBusy())
        heap->collectAllGarbage();
}

/*
    JSTypeGetCFArrayCallBacks
*/
void JSTypeGetCFArrayCallBacks(CFArrayCallBacks* outCallBacks)
{
    if (outCallBacks)
    {
        outCallBacks->version = 1;
        outCallBacks->retain = (CFArrayRetainCallBack)JSCFRetain;
        outCallBacks->release = (CFArrayReleaseCallBack)JSCFRelease;
        outCallBacks->copyDescription = (CFArrayCopyDescriptionCallBack)JSCopyDescription;
        outCallBacks->equal = (CFArrayEqualCallBack)JSEqual;
    }
}


/*
    JSCFRetain
*/
void *JSCFRetain(CFAllocatorRef allocator, const void *value)
{
    JSRetain((JSTypeRef)value);
    return (void*)value;
}

/*
    JSCFRelease
*/
void JSCFRelease(CFAllocatorRef allocator, const void *value)
{
    JSRelease((JSTypeRef)value);
}


/*
    JSObjectCreateWithCFType
*/
JSObjectRef JSObjectCreateWithCFType(CFTypeRef inRef)
{
    JSObjectCallBacks callBacks;
    JSObjectRef cfJSObject = nil;
    if (inRef)
    {
        callBacks.dispose = CFJSObjectDispose;
        callBacks.equal = CFJSObjectEqual;
        callBacks.copyCFValue = CFJSObjectCopyCFValue;
        callBacks.copyProperty = CFJSObjectCopyProperty;
        callBacks.setProperty = CFJSObjectSetProperty;
        callBacks.callFunction = 0;
        callBacks.copyPropertyNames = CFJSObjectCopyPropertyNames;
        cfJSObject = JSObjectCreateInternal((void*)CFRetain(inRef), &callBacks, 0, kJSUserObjectDataTypeCFType );
    }
    return cfJSObject;
}

/*
    CFJSObjectDispose
*/
void CFJSObjectDispose(void *data)
{
    if (data)
    {
        CFRelease((JSTypeRef)data);
    }
}

CFArrayRef JSObjectCopyPropertyNames(JSObjectRef ref)
{
    CFArrayRef result = 0;
    JSUserObject* ptr = (JSUserObject*)ref;
    if (ptr && (ptr->GetTypeID() == kJSObjectTypeID))
    {
        result = ptr->CopyPropertyNames();
    }
    return result;
}
/*
    CFJSObjectCopyProperty
*/
JSObjectRef CFJSObjectCopyProperty(void *data, CFStringRef propertyName)
{
    JSObjectRef result = 0;
    if (data && propertyName)
    {
        CFTypeRef cfResult = 0;
        if (CFGetTypeID(data) == CFDictionaryGetTypeID())
        {
            if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
            {
                int len = CFDictionaryGetCount((CFDictionaryRef)data);
                cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
            }
            else
            {
                cfResult = RetainCFType(CFDictionaryGetValue((CFDictionaryRef)data, propertyName));
            }
        }
        else if (CFGetTypeID(data) == CFArrayGetTypeID())
        {
            if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
            {
                int len = CFArrayGetCount((CFArrayRef)data);
                cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
            }
            else
            {
                SInt32 index = CFStringGetIntValue(propertyName);
                CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
                if (index >= 0 && index < arrayCount)
                {
                    cfResult = RetainCFType(CFArrayGetValueAtIndex((CFArrayRef)data, index));
                }
            }
        }
        else if (CFGetTypeID(data) == CFStringGetTypeID())
        {
            if (CFStringCompare(propertyName, CFSTR("length"), 0) == kCFCompareEqualTo)
            {
                int len = CFStringGetLength((CFStringRef)data);
                cfResult = CFNumberCreate(0, kCFNumberIntType, &len);
            }
        }
        if (cfResult)
        {
            result = JSObjectCreateWithCFType(cfResult);
            CFRelease(cfResult);
        }
    }
    return result;
}


/*
    CFJSObjectSetProperty
*/
void CFJSObjectSetProperty(void *data, CFStringRef propertyName, JSObjectRef jsValue)
{
    if (data && propertyName)
    {
        CFTypeRef cfValue = JSObjectCopyCFValue(jsValue);

        if (cfValue)
        {
            if (CFGetTypeID(data) == CFDictionaryGetTypeID())
            {
                CFDictionarySetValue((CFMutableDictionaryRef)data, propertyName, cfValue);
            }
            else if (CFGetTypeID(data) == CFArrayGetTypeID())
            {
                SInt32 index = CFStringGetIntValue(propertyName);
                CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
                if (index >= 0)
                {
                    for (; arrayCount < index; arrayCount++)
                    {
                        CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
                    }
                    CFArraySetValueAtIndex((CFMutableArrayRef)data, index, cfValue);
                }
            }
            CFRelease(cfValue);
        }
        else
        {
            if (CFGetTypeID(data) == CFDictionaryGetTypeID())
            {
                CFDictionaryRemoveValue((CFMutableDictionaryRef)data, propertyName);
            }
            else if (CFGetTypeID(data) == CFArrayGetTypeID())
            {
                SInt32 index = CFStringGetIntValue(propertyName);
                CFIndex arrayCount = CFArrayGetCount((CFArrayRef)data);
                if (index >= 0)
                {
                    for (; arrayCount < index; arrayCount++)
                    {
                        CFArrayAppendValue((CFMutableArrayRef)data, GetCFNull());
                    }
                    CFArraySetValueAtIndex((CFMutableArrayRef)data, index, GetCFNull());
                }
            }
        }
    }
}


/*
    CFJSObjectCopyCFValue
*/
CFTypeRef CFJSObjectCopyCFValue(void *data)
{
    CFTypeRef result = 0;
    if (data)
    {
        result = (CFTypeRef)CFRetain(data);
    }
    return result;
}

/*
    CFJSObjectCopyCFValue
*/
UInt8 CFJSObjectEqual(void *data1, void *data2)
{
    UInt8 result = false;
    if (data1 && data2)
    {
        CFEqual((CFTypeRef)data1, (CFTypeRef)data2);
    }
    return result;
}


/*
    CFJSObjectCopyPropertyNames
*/
CFArrayRef CFJSObjectCopyPropertyNames(void *data)
{
    CFMutableArrayRef result = 0;
    if (data)
    {
        CFTypeID cfType = CFGetTypeID(data);
        if (cfType == CFDictionaryGetTypeID())
        {
            CFIndex count = CFDictionaryGetCount((CFDictionaryRef)data);
            if (count)
            {
                CFTypeRef* keys = (CFTypeRef*)malloc(sizeof(CFTypeRef)*count);
                if (keys)
                {
                    int i;
                    CFDictionaryGetKeysAndValues((CFDictionaryRef)data, (const void **)keys, 0);
                    for (i = 0; i < count; i++)
                    {
                        CFStringRef key = (CFStringRef)keys[i];
                        if (CFGetTypeID(key) != CFStringGetTypeID()) continue;

                        if (!result) result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
                        if (!result) continue;

                        CFArrayAppendValue(result, key);
                    }
                    free(keys);
                }
            }
        }
    }
    return result;
}




CFMutableArrayRef JSCreateCFArrayFromJSArray(CFArrayRef array)
{
    CFIndex count = array ? CFArrayGetCount(array) : 0;
    CFMutableArrayRef cfArray = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
    CFIndex i;

    for (i = 0; cfArray && i <  count; i++)
    {
        JSObjectRef jsValue = (JSObjectRef)CFArrayGetValueAtIndex(array, i);
        CFTypeRef cfvalue = JSObjectCopyCFValue(jsValue);
        if (cfvalue)
        {
            CFArrayAppendValue(cfArray, cfvalue);
            CFRelease(cfvalue);
        }
        else
        {
            CFArrayAppendValue(cfArray, GetCFNull());
        }
    }
    return cfArray;
}

CFMutableArrayRef JSCreateJSArrayFromCFArray(CFArrayRef array)
{
    initializeThreading();

    CFIndex count = array ? CFArrayGetCount(array) : 0;
    CFArrayCallBacks arrayCallbacks;
    CFMutableArrayRef jsArray;
    CFIndex i;

    JSTypeGetCFArrayCallBacks(&arrayCallbacks);
    jsArray = CFArrayCreateMutable(0, 0, &arrayCallbacks);

    for (i = 0; array && i <  count; i++)
    {
        CFTypeRef cfValue = (CFTypeRef)CFArrayGetValueAtIndex(array, i);
        JSObjectRef jsValue = JSObjectCreateWithCFType(cfValue);

        if (!jsValue) jsValue = JSObjectCreateWithCFType(GetCFNull());
        if (jsValue)
        {
            CFArrayAppendValue(jsArray, jsValue);
            JSRelease(jsValue);
        }
    }
    return jsArray;
}


void JSLockInterpreter()
{
    initializeThreading();
    JSLock::lock(LockForReal);
}


void JSUnlockInterpreter()
{
    JSLock::unlock(LockForReal);
}
