/*
 * Copyright (C) 2004, 2006, 2007, 2008, 2009 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. 
 */

#import "DOMInternal.h"

#import "DOMNodeInternal.h"
#import <WebCore/Document.h>
#import <WebCore/Frame.h>
#import <WebCore/JSNode.h>
#import <WebCore/ScriptController.h>
#import <WebCore/WebScriptObjectPrivate.h>
#import <WebCore/runtime_root.h>
#import <wtf/HashMap.h>
#import <wtf/Lock.h>
#import <wtf/NeverDestroyed.h>

#if PLATFORM(IOS_FAMILY)
#define NEEDS_WRAPPER_CACHE_LOCK 1
#endif

//------------------------------------------------------------------------------------------
// Wrapping WebCore implementation objects

#ifdef NEEDS_WRAPPER_CACHE_LOCK
static Lock wrapperCacheLock;
static HashMap<DOMObjectInternal*, NSObject *>& wrapperCache() WTF_REQUIRES_LOCK(wrapperCacheLock)
#else
static HashMap<DOMObjectInternal*, NSObject *>& wrapperCache()
#endif
{
    static NeverDestroyed<HashMap<DOMObjectInternal*, NSObject *>> map;
    return map;
}

NSObject* getDOMWrapper(DOMObjectInternal* impl)
{
#ifdef NEEDS_WRAPPER_CACHE_LOCK
    Locker stateLocker { wrapperCacheLock };
#endif
    return wrapperCache().get(impl);
}

void addDOMWrapper(NSObject* wrapper, DOMObjectInternal* impl)
{
#ifdef NEEDS_WRAPPER_CACHE_LOCK
    Locker stateLocker { wrapperCacheLock };
#endif
    wrapperCache().set(impl, wrapper);
}

void removeDOMWrapper(DOMObjectInternal* impl)
{
#ifdef NEEDS_WRAPPER_CACHE_LOCK
    Locker stateLocker { wrapperCacheLock };
#endif
    wrapperCache().remove(impl);
}

//------------------------------------------------------------------------------------------

@implementation WebScriptObject (WebScriptObjectInternal)

// Only called by DOMObject subclass.
- (id)_init
{
    self = [super init];

    if (![self isKindOfClass:[DOMObject class]]) {
        [NSException raise:NSGenericException format:@"+%@: _init is an internal initializer", [self class]];
        return nil;
    }

    _private = [[WebScriptObjectPrivate alloc] init];
    _private->isCreatedByDOMWrapper = YES;
    
    return self;
}

- (void)_initializeScriptDOMNodeImp
{
    ASSERT(_private->isCreatedByDOMWrapper);
    
    if (![self isKindOfClass:[DOMNode class]]) {
        // DOMObject can't map back to a document, and thus an interpreter,
        // so for now only create wrappers for DOMNodes.
        return;
    }
    
    // Extract the WebCore::Node from the ObjectiveC wrapper.
    DOMNode *n = (DOMNode *)self;
    WebCore::Node *nodeImpl = core(n);

    // Dig up Interpreter and ExecState.
    WebCore::Frame *frame = nodeImpl->document().frame();
    if (!frame)
        return;

    // The global object which should own this node - FIXME: does this need to be isolated-world aware?
    WebCore::JSDOMGlobalObject* globalObject = frame->script().globalObject(WebCore::mainThreadNormalWorld());

    // Get (or create) a cached JS object for the DOM node.
    JSC::JSObject *scriptImp = asObject(WebCore::toJS(globalObject, globalObject, nodeImpl));

    JSC::Bindings::RootObject* rootObject = frame->script().bindingRootObject();

    [self _setImp:scriptImp originRootObject:rootObject rootObject:rootObject];
}

@end
