/*
 * Copyright (C) 2015 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 "config.h"
#import "TestRunnerWKWebView.h"

#import "WebKitTestRunnerDraggingInfo.h"
#import <WebKit/WKUIDelegatePrivate.h>
#import <wtf/Assertions.h>
#import <wtf/BlockPtr.h>
#import <wtf/Optional.h>
#import <wtf/RetainPtr.h>

#if PLATFORM(IOS_FAMILY)
#import "UIKitSPI.h"
#import <WebKit/WKWebViewPrivate.h>
@interface WKWebView ()

// FIXME: move these to WKWebView_Private.h
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view;
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale;
- (void)_didFinishScrolling;
- (void)_scheduleVisibleContentRectUpdate;

@end
#endif

struct CustomMenuActionInfo {
    RetainPtr<NSString> name;
    BOOL dismissesAutomatically { NO };
    BlockPtr<void()> callback;
};

@interface TestRunnerWKWebView () <WKUIDelegatePrivate> {
    RetainPtr<NSNumber> m_stableStateOverride;
    BOOL _isInteractingWithFormControl;
    BOOL _scrollingUpdatesDisabled;
    Optional<CustomMenuActionInfo> _customMenuActionInfo;
    RetainPtr<NSArray<NSString *>> _allowedMenuActions;
}

@property (nonatomic, copy) void (^zoomToScaleCompletionHandler)(void);
@property (nonatomic, copy) void (^retrieveSpeakSelectionContentCompletionHandler)(void);
@property (nonatomic, getter=isShowingKeyboard, setter=setIsShowingKeyboard:) BOOL showingKeyboard;
@property (nonatomic, getter=isShowingMenu, setter=setIsShowingMenu:) BOOL showingMenu;
@property (nonatomic, getter=isDismissingMenu, setter=setIsDismissingMenu:) BOOL dismissingMenu;
@property (nonatomic, getter=isShowingPopover, setter=setIsShowingPopover:) BOOL showingPopover;

@end

@implementation TestRunnerWKWebView

@dynamic _stableStateOverride;

#if PLATFORM(MAC)
IGNORE_WARNINGS_BEGIN("deprecated-implementations")
- (void)dragImage:(NSImage *)anImage at:(NSPoint)viewLocation offset:(NSSize)initialOffset event:(NSEvent *)event pasteboard:(NSPasteboard *)pboard source:(id)sourceObj slideBack:(BOOL)slideFlag
IGNORE_WARNINGS_END
{
    RetainPtr<WebKitTestRunnerDraggingInfo> draggingInfo = adoptNS([[WebKitTestRunnerDraggingInfo alloc] initWithImage:anImage offset:initialOffset pasteboard:pboard source:sourceObj]);
    [self draggingUpdated:draggingInfo.get()];
}
#endif

- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
{
    if (self = [super initWithFrame:frame configuration:configuration]) {
        NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
#if PLATFORM(MAC)
        [center addObserver:self selector:@selector(_didShowMenu) name:NSMenuDidBeginTrackingNotification object:nil];
        [center addObserver:self selector:@selector(_didHideMenu) name:NSMenuDidEndTrackingNotification object:nil];
#else
        [center addObserver:self selector:@selector(_invokeShowKeyboardCallbackIfNecessary) name:UIKeyboardDidShowNotification object:nil];
        [center addObserver:self selector:@selector(_invokeHideKeyboardCallbackIfNecessary) name:UIKeyboardDidHideNotification object:nil];
        [center addObserver:self selector:@selector(_didShowMenu) name:UIMenuControllerDidShowMenuNotification object:nil];
        [center addObserver:self selector:@selector(_willHideMenu) name:UIMenuControllerWillHideMenuNotification object:nil];
        [center addObserver:self selector:@selector(_didHideMenu) name:UIMenuControllerDidHideMenuNotification object:nil];
        [center addObserver:self selector:@selector(_willPresentPopover) name:@"UIPopoverControllerWillPresentPopoverNotification" object:nil];
        [center addObserver:self selector:@selector(_didDismissPopover) name:@"UIPopoverControllerDidDismissPopoverNotification" object:nil];
        self.UIDelegate = self;
#endif
    }
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    [self resetInteractionCallbacks];

    self.zoomToScaleCompletionHandler = nil;
    self.retrieveSpeakSelectionContentCompletionHandler = nil;

    [super dealloc];
}

- (void)_didShowMenu
{
    if (self.showingMenu)
        return;

    self.showingMenu = YES;
    if (self.didShowMenuCallback)
        self.didShowMenuCallback();
}

- (void)_didHideMenu
{
#if PLATFORM(IOS_FAMILY)
    self.dismissingMenu = NO;
#endif

    if (!self.showingMenu)
        return;

    self.showingMenu = NO;
    if (self.didHideMenuCallback)
        self.didHideMenuCallback();
}

- (void)dismissActiveMenu
{
#if PLATFORM(IOS_FAMILY)
    [self resignFirstResponder];
#else
    auto menu = retainPtr(self._activeMenu);
    [menu removeAllItems];
    [menu update];
    [menu cancelTracking];
#endif
}

- (void)resetInteractionCallbacks
{
    self.didShowMenuCallback = nil;
    self.didHideMenuCallback = nil;
#if PLATFORM(IOS_FAMILY)
    self.didStartFormControlInteractionCallback = nil;
    self.didEndFormControlInteractionCallback = nil;
    self.didShowContextMenuCallback = nil;
    self.didDismissContextMenuCallback = nil;
    self.willBeginZoomingCallback = nil;
    self.didEndZoomingCallback = nil;
    self.didShowKeyboardCallback = nil;
    self.didHideKeyboardCallback = nil;
    self.willPresentPopoverCallback = nil;
    self.didDismissPopoverCallback = nil;
    self.didEndScrollingCallback = nil;
    self.rotationDidEndCallback = nil;
#endif // PLATFORM(IOS_FAMILY)
}

#if PLATFORM(IOS_FAMILY)

- (void)_willHideMenu
{
    self.dismissingMenu = YES;
}

- (void)didStartFormControlInteraction
{
    _isInteractingWithFormControl = YES;

    if (self.didStartFormControlInteractionCallback)
        self.didStartFormControlInteractionCallback();
}

- (void)didEndFormControlInteraction
{
    _isInteractingWithFormControl = NO;

    if (self.didEndFormControlInteractionCallback)
        self.didEndFormControlInteractionCallback();
}

- (BOOL)isInteractingWithFormControl
{
    return _isInteractingWithFormControl;
}

- (void)_didShowContextMenu
{
    if (self.didShowContextMenuCallback)
        self.didShowContextMenuCallback();
}

- (void)_didDismissContextMenu
{
    if (self.didDismissContextMenuCallback)
        self.didDismissContextMenuCallback();
}

- (BOOL)becomeFirstResponder
{
    BOOL wasFirstResponder = self.isFirstResponder;
    BOOL becameFirstResponder = [super becomeFirstResponder];
    if (!wasFirstResponder && becameFirstResponder)
        [self _addCustomItemToMenuControllerIfNecessary];
    return becameFirstResponder;
}

- (void)_addCustomItemToMenuControllerIfNecessary
{
    if (!_customMenuActionInfo)
        return;

    auto item = adoptNS([[UIMenuItem alloc] initWithTitle:_customMenuActionInfo->name.get() action:@selector(performCustomAction:)]);
    [item setDontDismiss:!_customMenuActionInfo->dismissesAutomatically];
    UIMenuController *controller = UIMenuController.sharedMenuController;
    controller.menuItems = @[ item.get() ];
    [controller update];
}

- (void)installCustomMenuAction:(NSString *)name dismissesAutomatically:(BOOL)dismissesAutomatically callback:(dispatch_block_t)callback
{
    _customMenuActionInfo = {{ name, dismissesAutomatically, callback }};
    [self _addCustomItemToMenuControllerIfNecessary];
}

- (void)setAllowedMenuActions:(NSArray<NSString *> *)actions
{
    _allowedMenuActions = actions;
}

- (void)resetCustomMenuAction
{
    _customMenuActionInfo.reset();
    UIMenuController.sharedMenuController.menuItems = @[ ];
}

- (void)performCustomAction:(id)sender
{
    if (!_customMenuActionInfo)
        return;

    if (!_customMenuActionInfo->callback) {
        ASSERT_NOT_REACHED();
        return;
    }

    _customMenuActionInfo->callback();
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    BOOL isCustomAction = action == @selector(performCustomAction:);
    BOOL canPerformActionByDefault = [super canPerformAction:action withSender:sender];
    if (isCustomAction)
        canPerformActionByDefault = _customMenuActionInfo.hasValue();

    if (canPerformActionByDefault && _allowedMenuActions && sender == UIMenuController.sharedMenuController) {
        BOOL isAllowed = NO;
        if (isCustomAction) {
            for (NSString *allowedAction in _allowedMenuActions.get()) {
                if ([[_customMenuActionInfo->name lowercaseString] isEqualToString:allowedAction.lowercaseString]) {
                    isAllowed = YES;
                    break;
                }
            }
        } else {
            for (NSString *allowedAction in _allowedMenuActions.get()) {
                NSString *lowercaseSelectorName = [[allowedAction lowercaseString] stringByAppendingString:@":"];
                if ([NSStringFromSelector(action).lowercaseString isEqualToString:lowercaseSelectorName]) {
                    isAllowed = YES;
                    break;
                }
            }
        }
        if (!isAllowed)
            return NO;
    }
    return canPerformActionByDefault;
}


- (void)zoomToScale:(double)scale animated:(BOOL)animated completionHandler:(void (^)(void))completionHandler
{
    ASSERT(!self.zoomToScaleCompletionHandler);

    if (self.scrollView.zoomScale == scale) {
        dispatch_async(dispatch_get_main_queue(), ^{
            completionHandler();
        });
        return;
    }

    self.zoomToScaleCompletionHandler = completionHandler;
    [self.scrollView setZoomScale:scale animated:animated];
}

- (void)_invokeShowKeyboardCallbackIfNecessary
{
    if (self.showingKeyboard)
        return;

    self.showingKeyboard = YES;
    if (self.didShowKeyboardCallback)
        self.didShowKeyboardCallback();
}

- (void)_invokeHideKeyboardCallbackIfNecessary
{
    if (!self.showingKeyboard)
        return;

    self.showingKeyboard = NO;
    if (self.didHideKeyboardCallback)
        self.didHideKeyboardCallback();
}

- (void)_willPresentPopover
{
    if (self.showingPopover)
        return;

    self.showingPopover = YES;
    if (self.willPresentPopoverCallback)
        self.willPresentPopoverCallback();
}

- (void)_didDismissPopover
{
    if (!self.showingPopover)
        return;

    self.showingPopover = NO;
    if (self.didDismissPopoverCallback)
        self.didDismissPopoverCallback();
}

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
    [super scrollViewWillBeginZooming:scrollView withView:view];

    if (self.willBeginZoomingCallback)
        self.willBeginZoomingCallback();
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
    [super scrollViewDidEndZooming:scrollView withView:view atScale:scale];
    
    if (self.didEndZoomingCallback)
        self.didEndZoomingCallback();

    if (self.zoomToScaleCompletionHandler) {
        self.zoomToScaleCompletionHandler();
        self.zoomToScaleCompletionHandler = nullptr;
    }
}

- (void)_didFinishScrolling
{
    [super _didFinishScrolling];

    if (self.didEndScrollingCallback)
        self.didEndScrollingCallback();
}

- (NSNumber *)_stableStateOverride
{
    return m_stableStateOverride.get();
}

- (void)_setStableStateOverride:(NSNumber *)overrideBoolean
{
    m_stableStateOverride = overrideBoolean;
    [self _scheduleVisibleContentRectUpdate];
}

- (BOOL)_scrollingUpdatesDisabledForTesting
{
    return _scrollingUpdatesDisabled;
}

- (void)_setScrollingUpdatesDisabledForTesting:(BOOL)disabled
{
    _scrollingUpdatesDisabled = disabled;
}

- (void)_didEndRotation
{
    if (self.rotationDidEndCallback)
        self.rotationDidEndCallback();
}

- (void)_accessibilityDidGetSpeakSelectionContent:(NSString *)content
{
    self.accessibilitySpeakSelectionContent = content;
    if (self.retrieveSpeakSelectionContentCompletionHandler)
        self.retrieveSpeakSelectionContentCompletionHandler();
}

- (void)accessibilityRetrieveSpeakSelectionContentWithCompletionHandler:(void (^)(void))completionHandler
{
    self.retrieveSpeakSelectionContentCompletionHandler = completionHandler;
    [self _accessibilityRetrieveSpeakSelectionContent];
}

- (void)setOverrideSafeAreaInsets:(UIEdgeInsets)insets
{
    _overrideSafeAreaInsets = insets;
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000
    [self _updateSafeAreaInsets];
#endif
}

- (UIEdgeInsets)_safeAreaInsetsForFrame:(CGRect)frame inSuperview:(UIView *)view
{
    return _overrideSafeAreaInsets;
}

#pragma mark - WKUIDelegatePrivate

// In extra zoom mode, fullscreen form control UI takes on the same role as keyboards and input view controllers
// in UIKit. As such, we allow keyboard presentation and dismissal callbacks to work in extra zoom mode as well.
- (void)_webView:(WKWebView *)webView didPresentFocusedElementViewController:(UIViewController *)controller
{
    [self _invokeShowKeyboardCallbackIfNecessary];
}

- (void)_webView:(WKWebView *)webView didDismissFocusedElementViewController:(UIViewController *)controller
{
    [self _invokeHideKeyboardCallbackIfNecessary];
}

#endif // PLATFORM(IOS_FAMILY)

@end
