/*
 * Copyright (C) 2012 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.
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "config.h"
#import "MockWebNotificationProvider.h"

#import <WebKit/WebSecurityOriginPrivate.h>

@implementation MockWebNotificationProvider

+ (MockWebNotificationProvider *)shared
{
    static MockWebNotificationProvider *provider = [[MockWebNotificationProvider alloc] init];
    return provider;
}

- (id)init
{
    if (!(self = [super init]))
        return nil;
    _permissions = adoptNS([[NSMutableDictionary alloc] init]);
    return self;
}

- (void)registerWebView:(WebView *)webView
{
    ASSERT(!_registeredWebViews.contains(webView));
    _registeredWebViews.add(webView);
}

- (void)unregisterWebView:(WebView *)webView
{
    ASSERT(_registeredWebViews.contains(webView));
    _registeredWebViews.remove(webView);
}

- (void)showNotification:(WebNotification *)notification fromWebView:(WebView *)webView
{
    ASSERT(_registeredWebViews.contains(webView));

    uint64_t notificationID = [notification notificationID];
    _notifications.add(notificationID, notification);
    _notificationViewMap.add(notificationID, webView);

    [webView _notificationDidShow:notificationID];
}

- (void)cancelNotification:(WebNotification *)notification
{
    uint64_t notificationID = [notification notificationID];
    ASSERT(_notifications.contains(notificationID));

    [_notificationViewMap.get(notificationID) _notificationsDidClose:[NSArray arrayWithObject:[NSNumber numberWithUnsignedLongLong:notificationID]]];
}

- (void)notificationDestroyed:(WebNotification *)notification
{
    _notifications.remove([notification notificationID]);
    _notificationViewMap.remove([notification notificationID]);
}

- (void)clearNotifications:(NSArray *)notificationIDs
{
    for (NSNumber *notificationID in notificationIDs) {
        uint64_t id = [notificationID unsignedLongLongValue];
        RetainPtr<WebNotification> notification = _notifications.take(id);
        _notificationViewMap.remove(id);
    }
}

- (void)webView:(WebView *)webView didShowNotification:(uint64_t)notificationID
{
    [_notifications.get(notificationID).get() dispatchShowEvent];
}

- (void)webView:(WebView *)webView didClickNotification:(uint64_t)notificationID
{
    [_notifications.get(notificationID).get() dispatchClickEvent];
}

- (void)webView:(WebView *)webView didCloseNotifications:(NSArray *)notificationIDs
{
    for (NSNumber *notificationID in notificationIDs) {
        uint64_t id = [notificationID unsignedLongLongValue];
        NotificationIDMap::iterator it = _notifications.find(id);
        ASSERT(it != _notifications.end());
        [it->value.get() dispatchCloseEvent];
        _notifications.remove(it);
        _notificationViewMap.remove(id);
    }
}

- (void)simulateWebNotificationClick:(uint64_t)notificationID
{
    ASSERT(_notifications.contains(notificationID));
    [_notificationViewMap.get(notificationID) _notificationDidClick:notificationID];
}

- (WebNotificationPermission)policyForOrigin:(WebSecurityOrigin *)origin
{
    NSNumber *permission = [_permissions.get() objectForKey:[origin stringValue]];
    if (!permission)
        return WebNotificationPermissionNotAllowed;
    if ([permission boolValue])
        return WebNotificationPermissionAllowed;
    return WebNotificationPermissionDenied;
}

- (void)setWebNotificationOrigin:(NSString *)origin permission:(BOOL)allowed
{
    [_permissions.get() setObject:[NSNumber numberWithBool:allowed] forKey:origin];
}

- (void)removeAllWebNotificationPermissions
{
    [_permissions.get() removeAllObjects];
}

- (void)reset
{
    _notifications.clear();
    _notificationViewMap.clear();
    [self removeAllWebNotificationPermissions];
}

@end
