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

#import "WebScriptWorld.h"

#import "WebScriptWorldInternal.h"
#import <WebCore/JSDOMBinding.h>
#import <WebCore/ScriptController.h>
#import <JavaScriptCore/APICast.h>
#import <JavaScriptCore/JSContextInternal.h>
#import <wtf/RefPtr.h>

@interface WebScriptWorldPrivate : NSObject {
@public
    RefPtr<WebCore::DOMWrapperWorld> world;
}
@end

@implementation WebScriptWorldPrivate
@end

typedef HashMap<WebCore::DOMWrapperWorld*, WebScriptWorld*> WorldMap;
static WorldMap& allWorlds()
{
    static WorldMap& map = *new WorldMap;
    return map;
}

@implementation WebScriptWorld

- (id)initWithWorld:(Ref<WebCore::DOMWrapperWorld>&&)world
{
    self = [super init];
    if (!self)
        return nil;

    _private = [[WebScriptWorldPrivate alloc] init];
    _private->world = WTFMove(world);

    ASSERT_ARG(world, !allWorlds().contains(_private->world.get()));
    allWorlds().add(_private->world.get(), self);

    return self;
}

- (id)init
{
    return [self initWithWorld:WebCore::ScriptController::createWorld("WebScriptWorld"_s, WebCore::ScriptController::WorldType::User)];
}

- (void)unregisterWorld
{
    _private->world->clearWrappers();
}

- (void)dealloc
{
    ASSERT(allWorlds().contains(_private->world.get()));
    allWorlds().remove(_private->world.get());

    [_private release];
    _private = nil;
    [super dealloc];
}

+ (WebScriptWorld *)standardWorld
{
    static WebScriptWorld *world = [[WebScriptWorld alloc] initWithWorld:WebCore::mainThreadNormalWorld()];
    return world;
}

+ (WebScriptWorld *)world
{
    return [[[self alloc] init] autorelease];
}

+ (WebScriptWorld *)scriptWorldForGlobalContext:(JSGlobalContextRef)context
{
    return [self findOrCreateWorld:WebCore::currentWorld(*toJS(context))];
}

#if JSC_OBJC_API_ENABLED
+ (WebScriptWorld *)scriptWorldForJavaScriptContext:(JSContext *)context
{
    return [self scriptWorldForGlobalContext:[context JSGlobalContextRef]];
}
#endif

@end

@implementation WebScriptWorld (WebInternal)

WebCore::DOMWrapperWorld* core(WebScriptWorld *world)
{
    return world ? world->_private->world.get() : 0;
}

+ (WebScriptWorld *)findOrCreateWorld:(WebCore::DOMWrapperWorld&)world
{
    if (&world == &WebCore::mainThreadNormalWorld())
        return [self standardWorld];

    if (WebScriptWorld *existingWorld = allWorlds().get(&world))
        return existingWorld;

    return [[[self alloc] initWithWorld:world] autorelease];
}

@end
