/*
 * Copyright (C) 2006 Apple Inc.  All rights reserved.
 * Copyright (C) 2006 James G. Speth (speth@end.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 THE AUTHOR ``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 AUTHOR 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. 
*/

#import "config.h"
#import "ObjCPlugin.h"

#import <objc/runtime.h>
#import <WebKit/WebKitLegacy.h>

// === NSObject category to expose almost everything to JavaScript ===

// Warning: this class introduces huge security weaknesses, and should only be used
// for testing inside of DumpRenderTree, and only with trusted code.  By default, it has
// the same restrictive behavior as the standard WebKit setup.  However, scripts can use the
// plugin's removeBridgeRestrictions: method to open up almost total access to the Cocoa
// frameworks.

static BOOL _allowsScriptsFullAccess = NO;

@interface NSObject (ObjCScriptAccess)

+ (void)setAllowsScriptsFullAccess:(BOOL)value;
+ (BOOL)allowsScriptsFullAccess;

@end

@implementation NSObject (ObjCScriptAccess)

+ (void)setAllowsScriptsFullAccess:(BOOL)value
{
    _allowsScriptsFullAccess = value;
}

+ (BOOL)allowsScriptsFullAccess
{
    return _allowsScriptsFullAccess;
}

+ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
{
    return !_allowsScriptsFullAccess;
}

+ (NSString *)webScriptNameForSelector:(SEL)selector
{
    return nil;
}

@end

@interface JSObjC : NSObject {
}

// expose some useful objc functions to the scripting environment
- (id)lookUpClass:(NSString *)name;
- (void)log:(NSString *)message;
- (id)retainObject:(id)obj;
- (id)classOfObject:(id)obj;
- (NSString *)classNameOfObject:(id)obj;

@end

@implementation JSObjC

+ (BOOL)isSelectorExcludedFromWebScript:(SEL)selector
{
    return NO;
}

+ (NSString *)webScriptNameForSelector:(SEL)selector
{
    return nil;
}

- (id)invokeDefaultMethodWithArguments:(NSArray *)args
{
    // this is a useful shortcut for accessing objective-c classes from the scripting
    // environment, e.g. 'var myObject = objc("NSObject").alloc().init();'
    if ([args count] == 1)
        return [self lookUpClass:[args objectAtIndex:0]];
    return nil;
}

- (id)lookUpClass:(NSString *)name
{
    return NSClassFromString(name);
}

- (void)log:(NSString *)message
{
    NSLog(@"%@", message);
}

- (id)retainObject:(id)obj
{
    CFRetain((__bridge CFTypeRef)obj);
    return obj;
}

- (id)classOfObject:(id)obj
{
    return (id)[obj class];
}

- (NSString *)classNameOfObject:(id)obj
{
    return NSStringFromClass([obj class]);
}

@end

@implementation ObjCPlugin

+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
    if (aSelector == @selector(removeBridgeRestrictions:))
        return NO;

    if (aSelector == @selector(echo:))
        return NO;

    if (aSelector == @selector(throwIfArgumentIsNotHello:))
        return NO;

    if (aSelector == @selector(methodMappedToLongName))
        return NO;

    NSString *selectorName = NSStringFromSelector(aSelector);
    if ([selectorName hasPrefix:@"testConversion"])
        return NO;

    return YES;
}

+ (NSString *)webScriptNameForSelector:(SEL)aSelector
{
    if (aSelector == @selector(echo:))
        return @"echo";

    if (aSelector == @selector(throwIfArgumentIsNotHello:))
        return @"throwIfArgumentIsNotHello";

    if (aSelector == @selector(methodMappedToLongName))
        return [@"" stringByPaddingToLength:4096 withString: @"long" startingAtIndex:0];

    return nil;
}

+ (NSString *)webScriptNameForKey:(const char *)key 
{
    if (strcmp(key, "throwOnDealloc") == 0)
      return @"throwOnDealloc";
    
    return nil;
}

+ (BOOL)isKeyExcludedFromWebScript:(const char *)key 
{
    if (strcmp(key, "throwOnDealloc") == 0)
      return NO;
    
    return YES;
}

- (void)removeBridgeRestrictions:(id)container
{
    // let scripts invoke any selector
    [NSObject setAllowsScriptsFullAccess:YES];
    
    // store a JSObjC instance into the provided container
    JSObjC *objc = [[JSObjC alloc] init];
    [container setValue:objc forKey:@"objc"];
    [objc release];
}

- (id)echo:(id)obj
{
    return obj;
}

- (void)throwIfArgumentIsNotHello:(NSString *)str 
{
    if (![str isEqualToString:@"Hello"]) 
        [WebScriptObject throwException:[NSString stringWithFormat:@"%@ != Hello", str]];
}

- (NSString *)methodMappedToLongName
{
    return @"methodMappedToLongName";
}

- (NSString *)testConversionColon:(int)useless
{
    return @"testConversionColon:(int)useless";
}

- (NSString *)testConversionEscapeChar$a_b$_:(int)useless
{
    return @"testConversionEscapeChar$a_b$_:(int)useless";
}

- (void)dealloc
{
    if (throwOnDealloc)
        [WebScriptObject throwException:@"Throwing exception on dealloc of ObjCPlugin"];
    
    [super dealloc];
}

@end
