/*
 * 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. 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 INC. 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 "CurrentThisInsideBlockGetterTest.h"

#if JSC_OBJC_API_ENABLED

#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>

static JSObjectRef CallAsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t, const JSValueRef[], JSValueRef*)
{
    JSObjectRef newObjectRef = NULL;
    NSMutableDictionary *constructorPrivateProperties = (__bridge NSMutableDictionary *)(JSObjectGetPrivate(constructor));
    NSDictionary *constructorDescriptor = constructorPrivateProperties[@"constructorDescriptor"];
    newObjectRef = JSObjectMake(ctx, NULL, NULL);
    NSDictionary *objectProperties = constructorDescriptor[@"objectProperties"];
    
    if (objectProperties) {
        JSValue *newObject = [JSValue valueWithJSValueRef:newObjectRef inContext:[JSContext contextWithJSGlobalContextRef:JSContextGetGlobalContext(ctx)]];
        for (NSString *objectProperty in objectProperties) {
            [newObject defineProperty:objectProperty descriptor:objectProperties[objectProperty]];
        }
    }
    
    return newObjectRef;
}

static void ConstructorFinalize(JSObjectRef object)
{
    NSMutableDictionary *privateProperties = (__bridge NSMutableDictionary *)(JSObjectGetPrivate(object));
    CFBridgingRelease((__bridge CFTypeRef)(privateProperties));
    JSObjectSetPrivate(object, NULL);
}

static JSClassRef ConstructorClass(void)
{
    static JSClassRef constructorClass = NULL;
    
    if (constructorClass == NULL) {
        JSClassDefinition classDefinition = kJSClassDefinitionEmpty;
        classDefinition.className = "Constructor";
        classDefinition.callAsConstructor = CallAsConstructor;
        classDefinition.finalize = ConstructorFinalize;
        constructorClass = JSClassCreate(&classDefinition);
    }
    
    return constructorClass;
}

@interface JSValue (ConstructorCreation)

+ (JSValue *)valueWithConstructorDescriptor:(NSDictionary *)constructorDescriptor inContext:(JSContext *)context;

@end

@implementation JSValue (ConstructorCreation)

+ (JSValue *)valueWithConstructorDescriptor:(id)constructorDescriptor inContext:(JSContext *)context
{
    NSMutableDictionary *privateProperties = [@{ @"constructorDescriptor" : constructorDescriptor } mutableCopy];
    JSGlobalContextRef ctx = [context JSGlobalContextRef];
    JSObjectRef constructorRef = JSObjectMake(ctx, ConstructorClass(), const_cast<void*>(CFBridgingRetain(privateProperties)));
    JSValue *constructor = [JSValue valueWithJSValueRef:constructorRef inContext:context];
    return constructor;
}

@end

@interface JSContext (ConstructorCreation)

- (JSValue *)valueWithConstructorDescriptor:(NSDictionary *)constructorDescriptor;

@end

@implementation JSContext (ConstructorCreation)

- (JSValue *)valueWithConstructorDescriptor:(id)constructorDescriptor
{
    return [JSValue valueWithConstructorDescriptor:constructorDescriptor inContext:self];
}

@end

void currentThisInsideBlockGetterTest()
{
    @autoreleasepool {
        JSContext *context = [[JSContext alloc] init];
        
        JSValue *myConstructor = [context valueWithConstructorDescriptor:@{
            @"objectProperties" : @{
                @"currentThis" : @{ JSPropertyDescriptorGetKey : ^{ return JSContext.currentThis; } },
            },
        }];
        
        JSValue *myObj1 = [myConstructor constructWithArguments:nil];
        NSLog(@"myObj1.currentThis: %@", myObj1[@"currentThis"]);
        JSValue *myObj2 = [myConstructor constructWithArguments:@[ @"bar" ]];
        NSLog(@"myObj2.currentThis: %@", myObj2[@"currentThis"]);
    }
}

#endif // JSC_OBJC_API_ENABLED
