/*
 * Copyright (C) 2006 Apple Computer, 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 "ObjCPlugin.h"
#import <objc/objc-runtime.h>
#import <WebKit/WebKit.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
{
    return [obj retain];
}

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

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

@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;

    return YES;
}

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

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

    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]];
}

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

@end
