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

#include "config.h"
#import "JavaScriptCore.h"

#if JS_OBJC_API_ENABLED

#import "APICast.h"
#import "APIShims.h"
#import "Error.h"
#import "JSBlockAdaptor.h"
#import "JSContextInternal.h"
#import "JSWrapperMap.h"
#import "JSValue.h"
#import "JSValueInternal.h"
#import "ObjcRuntimeExtras.h"
#import "Operations.h"
#import "wtf/OwnPtr.h"

extern "C" {
id __NSMakeSpecialForwardingCaptureBlock(const char *signature, void (^handler)(NSInvocation *));
}

class BlockArgument {
public:
    virtual ~BlockArgument();
    virtual JSValueRef get(NSInvocation *, NSInteger, JSContext *, JSValueRef*) = 0;

    OwnPtr<BlockArgument> m_next;
};

BlockArgument::~BlockArgument()
{
}

class BlockArgumentBoolean : public BlockArgument {
    virtual JSValueRef get(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef*) override
    {
        bool value;
        [invocation getArgument:&value atIndex:argumentNumber];
        return JSValueMakeBoolean(contextInternalContext(context), value);
    }
};

template<typename T>
class BlockArgumentNumeric : public BlockArgument {
    virtual JSValueRef get(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef*) override
    {
        T value;
        [invocation getArgument:&value atIndex:argumentNumber];
        return JSValueMakeNumber(contextInternalContext(context), value);
    }
};

class BlockArgumentId : public BlockArgument {
    virtual JSValueRef get(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef*) override
    {
        id value;
        [invocation getArgument:&value atIndex:argumentNumber];
        return objectToValue(context, value);
    }
};

class BlockArgumentStruct : public BlockArgument {
public:
    BlockArgumentStruct(NSInvocation *conversionInvocation, const char* encodedType)
        : m_conversionInvocation(conversionInvocation)
        , m_buffer(encodedType)
    {
    }
    
private:
    virtual JSValueRef get(NSInvocation *invocation, NSInteger argumentNumber, JSContext *context, JSValueRef*) override
    {
        [invocation getArgument:m_buffer atIndex:argumentNumber];

        [m_conversionInvocation setArgument:m_buffer atIndex:2];
        [m_conversionInvocation setArgument:&context atIndex:3];
        [m_conversionInvocation invokeWithTarget:[JSValue class]];

        JSValue *value;
        [m_conversionInvocation getReturnValue:&value];
        return valueInternalValue(value);
    }

    RetainPtr<NSInvocation> m_conversionInvocation;
    StructBuffer m_buffer;
};

class BlockArgumentTypeDelegate {
public:
    typedef BlockArgument* ResultType;

    template<typename T>
    static ResultType typeInteger()
    {
        return new BlockArgumentNumeric<T>;
    }

    template<typename T>
    static ResultType typeDouble()
    {
        return new BlockArgumentNumeric<T>;
    }

    static ResultType typeBool()
    {
        return new BlockArgumentBoolean;
    }

    static ResultType typeVoid()
    {
        RELEASE_ASSERT_NOT_REACHED();
        return 0;
    }

    static ResultType typeId()
    {
        return new BlockArgumentId;
    }

    static ResultType typeOfClass(const char*, const char*)
    {
        return new BlockArgumentId;
    }

    static ResultType typeBlock(const char*, const char*)
    {
        return 0;
    }

    static ResultType typeStruct(const char* begin, const char* end)
    {
        StringRange copy(begin, end);
        if (NSInvocation *invocation = valueToTypeInvocationFor(copy))
            return new BlockArgumentStruct(invocation, copy);
        return 0;
    }
};

class BlockResult {
public:
    virtual ~BlockResult()
    {
    }

    virtual void set(NSInvocation *, JSContext *, JSValueRef, JSValueRef*) = 0;
};

class BlockResultVoid : public BlockResult {
    virtual void set(NSInvocation *, JSContext *, JSValueRef, JSValueRef*) override
    {
    }
};

template<typename T>
class BlockResultInteger : public BlockResult {
    virtual void set(NSInvocation *invocation, JSContext *context, JSValueRef result, JSValueRef* exception) override
    {
        T value = (T)JSC::toInt32(JSValueToNumber(contextInternalContext(context), result, exception));
        [invocation setReturnValue:&value];
    }
};

template<typename T>
class BlockResultDouble : public BlockResult {
    virtual void set(NSInvocation *invocation, JSContext *context, JSValueRef result, JSValueRef* exception) override
    {
        T value = (T)JSValueToNumber(contextInternalContext(context), result, exception);
        [invocation setReturnValue:&value];
    }
};

class BlockResultBoolean : public BlockResult {
    virtual void set(NSInvocation *invocation, JSContext *context, JSValueRef result, JSValueRef*) override
    {
        bool value = JSValueToBoolean(contextInternalContext(context), result);
        [invocation setReturnValue:&value];
    }
};

class BlockResultStruct : public BlockResult {
public:
    BlockResultStruct(NSInvocation *conversionInvocation, const char* encodedType)
        : m_conversionInvocation(conversionInvocation)
        , m_buffer(encodedType)
    {
    }
    
private:
    virtual void set(NSInvocation *invocation, JSContext *context, JSValueRef result, JSValueRef*) override
    {
        JSValue *value = [JSValue valueWithValue:result inContext:context];
        [m_conversionInvocation invokeWithTarget:value];
        [m_conversionInvocation getReturnValue:m_buffer];
        [invocation setReturnValue:&value];
    }

    RetainPtr<NSInvocation> m_conversionInvocation;
    StructBuffer m_buffer;
};

@implementation JSBlockAdaptor {
    RetainPtr<NSString> m_signatureWithOffsets;
    RetainPtr<NSString> m_signatureWithoutOffsets;
    OwnPtr<BlockResult> m_result;
    OwnPtr<BlockArgument> m_arguments;
    size_t m_argumentCount;
}

// Helper function to add offset information back into a block signature.
static NSString *buildBlockSignature(NSString *prefix, const char* begin, const char* end, unsigned long long& offset, NSString *postfix)
{
    StringRange copy(begin, end);
    NSString *result = [NSString stringWithFormat:@"%@%s%@%@", prefix, copy.get(), @(offset), postfix];
    NSUInteger size;
    NSGetSizeAndAlignment(copy, &size, 0);
    if (size < 4)
        size = 4;
    offset += size;
    return result;
}

- (id)initWithBlockSignatureFromProtocol:(const char*)encodedType
{
    self = [super init];
    if (!self)
        return nil;

    m_signatureWithoutOffsets = [NSString stringWithUTF8String:encodedType];
    m_argumentCount = 0;

    // Currently only adapting JavaScript functions to blocks returning void.
    const char* resultTypeBegin = encodedType;
    if (*encodedType++ != 'v')
        return self;
    OwnPtr<BlockResult> result = adoptPtr(new BlockResultVoid);
    const char* resultTypeEnd = encodedType;

    if (encodedType[0] != '@' || encodedType[1] != '?')
        return self;
    encodedType += 2;

    // The first argument to a block is the block itself.
    NSString *signature = @"@?0";
    unsigned long long offset = sizeof(void*);

    OwnPtr<BlockArgument> arguments;
    OwnPtr<BlockArgument>* nextArgument = &arguments;
    while (*encodedType) {
        const char* begin = encodedType;
        OwnPtr<BlockArgument> argument = adoptPtr(parseObjCType<BlockArgumentTypeDelegate>(encodedType));
        if (!argument)
            return self;
        const char* end = encodedType;

        // Append the type & stack offset of this argument to the signature string.
        signature = buildBlockSignature(signature, begin, end, offset, @"");

        *nextArgument = argument.release();
        nextArgument = &(*nextArgument)->m_next;
        ++m_argumentCount;
    }

    // Prefix the signature with the return type & total stackframe size.
    // (this call will also add the return type size to the offset,
    // which is a nonsense, but harmless since this is the last use).
    signature = buildBlockSignature(@"", resultTypeBegin, resultTypeEnd, offset, signature);

    m_signatureWithOffsets = signature;
    m_result = result.release();
    m_arguments = arguments.release();

    return self;
}

// The JSBlockAdaptor stores the type string taken from the protocol. This string
// does not contain invocation layout information. The signature from the block
// does contain the stackframe offsets. Skip these when comparing strings.
- (bool)blockMatchesSignature:(id)block
{
    if (!_Block_has_signature(block))
        return false;

    const char* withoutOffsets = [m_signatureWithoutOffsets UTF8String];
    const char* signature = _Block_signature(block);

    while (true) {
        while (isdigit(*withoutOffsets))
            ++withoutOffsets;
        while (isdigit(*signature))
            ++signature;
        
        if (*withoutOffsets != *signature)
            return false;
        if (!*withoutOffsets)
            return true;
        ++withoutOffsets;
        ++signature;
    }
}

- (id)blockFromValue:(JSValueRef)argument inContext:(JSContext *)context withException:(JSValueRef*)exception
{
    JSGlobalContextRef contextRef = contextInternalContext(context);

    // Check for null/undefined.
    if (JSValueIsUndefined(contextRef, argument) || JSValueIsNull(contextRef, argument))
        return nil;

    JSObjectRef function = 0;
    if (id object = tryUnwrapObjcObject(contextRef, argument)) {
        // Check if the argument is an Objective-C block.
        if ([object isKindOfClass:getNSBlockClass()]) {
            if ([self blockMatchesSignature:object])
                return object;
        }
    } else if (m_signatureWithOffsets && JSValueIsObject(contextRef, argument)) {
        // Check if the argument is a JavaScript function
        // (and that were able to create a forwarding block for this signature).
        JSObjectRef object = JSValueToObject(contextRef, argument, exception);
        if (JSObjectIsFunction(contextRef, object))
            function = object;
    }

    if (!function) {
        JSC::APIEntryShim entryShim(toJS(contextRef));
        *exception = toRef(JSC::createTypeError(toJS(contextRef), "Invalid argument supplied for Objective-C block"));
        return nil;
    }

    // Captured variables.
    JSBlockAdaptor *adaptor = self;
    JSValue *value = [JSValue valueWithValue:function inContext:context];

    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=105895
    // Currently only supporting void functions.
    return __NSMakeSpecialForwardingCaptureBlock([m_signatureWithOffsets UTF8String], ^(NSInvocation *invocation){
        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=105894
        // Rather than requiring that the context be retained, it would probably be more
        // appropriate to use a new JSContext instance (creating one if necessary).
        // It would be nice if we could throw a JS exception here, but without a context we have
        // nothing to work with.
        JSContext *context = value.context;
        if (!context)
            return;
        JSGlobalContextRef contextRef = contextInternalContext(context);

        JSValueRef argumentArray[adaptor->m_argumentCount];

        size_t argumentNumber = 0;
        BlockArgument* arguments = adaptor->m_arguments.get();
        for (BlockArgument* argument = arguments; argument; argument = argument->m_next.get()) {
            JSValueRef exception = 0;
            argumentArray[argumentNumber] = argument->get(invocation, argumentNumber + 1, context, &exception);
            if (exception) {
                [context notifyException:exception];
                return;
            }
            
            ++argumentNumber;
        }
        size_t argumentCount = argumentNumber;

        JSValueRef exception = 0;
        JSObjectCallAsFunction(contextRef, JSValueToObject(contextRef, valueInternalValue(value), 0), 0, argumentCount, argumentArray, &exception);
        if (exception) {
            [context notifyException:exception];
            return;
        }
    });
}

@end

#endif
