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

#include "config.h"
#include "DragAndDropSimulator.h"

#if ENABLE(DRAG_SUPPORT) && PLATFORM(IOS_FAMILY)

#import "InstanceMethodSwizzler.h"
#import "PlatformUtilities.h"
#import "UIKitSPI.h"

#import <UIKit/UIDragInteraction.h>
#import <UIKit/UIDragItem.h>
#import <UIKit/UIDropInteraction.h>
#import <UIKit/UIInteraction.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/_WKFocusedElementInfo.h>
#import <WebKit/_WKFormInputSession.h>
#import <wtf/RetainPtr.h>
#import <wtf/SoftLinking.h>

SOFT_LINK_FRAMEWORK(UIKit)
SOFT_LINK(UIKit, UIApplicationInstantiateSingleton, void, (Class singletonClass), (singletonClass))

using namespace TestWebKitAPI;

@implementation WKWebView (DragAndDropTesting)

- (UIView *)_dragDropInteractionView
{
    return [self valueForKey:@"_currentContentView"];
}

- (id <UIDropInteractionDelegate>)dropInteractionDelegate
{
    return (id <UIDropInteractionDelegate>)self._dragDropInteractionView;
}

- (id <UIDragInteractionDelegate>)dragInteractionDelegate
{
    return (id <UIDragInteractionDelegate>)self._dragDropInteractionView;
}

- (UIDropInteraction *)dropInteraction
{
    UIView *interactionView = self._dragDropInteractionView;
    for (id <UIInteraction> interaction in interactionView.interactions) {
        if ([interaction isKindOfClass:[UIDropInteraction class]])
            return (UIDropInteraction *)interaction;
    }
    return nil;
}

- (UIDragInteraction *)dragInteraction
{
    UIView *interactionView = self._dragDropInteractionView;
    for (id <UIInteraction> interaction in interactionView.interactions) {
        if ([interaction isKindOfClass:[UIDragInteraction class]])
            return (UIDragInteraction *)interaction;
    }
    return nil;
}

@end

@implementation MockDragDropSession

- (instancetype)initWithItems:(NSArray <UIDragItem *>*)items location:(CGPoint)locationInWindow window:(UIWindow *)window allowMove:(BOOL)allowMove
{
    if (self = [super init]) {
        _mockItems = items;
        _mockLocationInWindow = locationInWindow;
        _window = window;
        _allowMove = allowMove;
    }
    return self;
}

- (BOOL)allowsMoveOperation
{
    return _allowMove;
}

- (BOOL)isRestrictedToDraggingApplication
{
    return NO;
}

- (BOOL)hasItemsConformingToTypeIdentifiers:(NSArray<NSString *> *)typeIdentifiers
{
    for (NSString *typeIdentifier in typeIdentifiers) {
        BOOL hasItemConformingToType = NO;
        for (UIDragItem *item in self.items)
            hasItemConformingToType |= [[item.itemProvider registeredTypeIdentifiers] containsObject:typeIdentifier];
        if (!hasItemConformingToType)
            return NO;
    }
    return YES;
}

- (BOOL)canLoadObjectsOfClass:(Class<NSItemProviderReading>)aClass
{
    for (UIDragItem *item in self.items) {
        if ([item.itemProvider canLoadObjectOfClass:aClass])
            return YES;
    }
    return NO;
}

- (BOOL)canLoadObjectsOfClasses:(NSArray<Class<NSItemProviderReading>> *)classes
{
    for (Class<NSItemProviderReading> aClass in classes) {
        BOOL canLoad = NO;
        for (UIDragItem *item in self.items)
            canLoad |= [item.itemProvider canLoadObjectOfClass:aClass];
        if (!canLoad)
            return NO;
    }
    return YES;
}

- (NSArray<UIDragItem *> *)items
{
    return _mockItems.get();
}

- (void)setItems:(NSArray<UIDragItem *> *)items
{
    _mockItems = items;
}

- (void)addItems:(NSArray<UIDragItem *> *)items
{
    if (![items count])
        return;

    if (![_mockItems count])
        _mockItems = items;
    else
        _mockItems = [_mockItems arrayByAddingObjectsFromArray:items];
}

- (CGPoint)locationInView:(UIView *)view
{
    return [_window convertPoint:_mockLocationInWindow toView:view];
}

@end

@implementation MockDropSession

- (instancetype)initWithProviders:(NSArray<NSItemProvider *> *)providers location:(CGPoint)locationInWindow window:(UIWindow *)window allowMove:(BOOL)allowMove
{
    auto items = adoptNS([[NSMutableArray alloc] init]);
    for (NSItemProvider *itemProvider in providers)
        [items addObject:[[[UIDragItem alloc] initWithItemProvider:itemProvider] autorelease]];

    return [super initWithItems:items.get() location:locationInWindow window:window allowMove:allowMove];
}

- (BOOL)isLocal
{
    return YES;
}

- (NSProgress *)progress
{
    return [NSProgress discreteProgressWithTotalUnitCount:100];
}

- (void)setProgressIndicatorStyle:(UIDropSessionProgressIndicatorStyle)progressIndicatorStyle
{
}

- (UIDropSessionProgressIndicatorStyle)progressIndicatorStyle
{
    return UIDropSessionProgressIndicatorStyleNone;
}

- (NSUInteger)operationMask
{
    return 0;
}

- (id <UIDragSession>)localDragSession
{
    return nil;
}

- (BOOL)hasItemsConformingToTypeIdentifier:(NSString *)typeIdentifier
{
    ASSERT_NOT_REACHED();
    return NO;
}

- (BOOL)canCreateItemsOfClass:(Class<NSItemProviderReading>)aClass
{
    ASSERT_NOT_REACHED();
    return NO;
}

- (NSProgress *)loadObjectsOfClass:(Class<NSItemProviderReading>)aClass completion:(void(^)(NSArray<__kindof id <NSItemProviderReading>> *objects))completion
{
    ASSERT_NOT_REACHED();
    return nil;
}

@end

@implementation MockDragSession {
    RetainPtr<id> _localContext;
}

- (instancetype)initWithWindow:(UIWindow *)window allowMove:(BOOL)allowMove
{
    return [super initWithItems:@[ ] location:CGPointZero window:window allowMove:allowMove];
}

- (NSUInteger)localOperationMask
{
    ASSERT_NOT_REACHED();
    return 0;
}

- (NSUInteger)externalOperationMask
{
    ASSERT_NOT_REACHED();
    return 0;
}

- (id)session
{
    return nil;
}

- (id)localContext
{
    return _localContext.get();
}

- (void)setLocalContext:(id)localContext
{
    _localContext = localContext;
}

@end

static double progressIncrementStep = 0.033;
static double progressTimeStep = 0.016;
static NSString *TestWebKitAPISimulateCancelAllTouchesNotificationName = @"TestWebKitAPISimulateCancelAllTouchesNotificationName";

static NSArray *dragAndDropEventNames()
{
    static NSArray *eventNames = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^() {
        eventNames = @[ @"dragenter", @"dragover", @"drop", @"dragleave", @"dragstart" ];
    });
    return eventNames;
}

@interface DragAndDropSimulatorApplication : UIApplication
@end

@implementation DragAndDropSimulatorApplication

IGNORE_WARNINGS_BEGIN("deprecated-implementations")
- (void)_cancelAllTouches
{
    [[NSNotificationCenter defaultCenter] postNotificationName:TestWebKitAPISimulateCancelAllTouchesNotificationName object:nil];
}
IGNORE_WARNINGS_END

@end

@interface DragAndDropSimulator () <UIDragAnimating>
@end

@implementation DragAndDropSimulator {
    RetainPtr<TestWKWebView> _webView;
    RetainPtr<MockDragSession> _dragSession;
    RetainPtr<MockDropSession> _dropSession;
    RetainPtr<NSMutableArray> _observedEventNames;
    RetainPtr<NSArray> _externalItemProviders;
    RetainPtr<NSArray> _sourceItemProviders;
    CGRect _finalSelectionStartRect;
    CGPoint _startLocation;
    CGPoint _endLocation;
    CGRect _lastKnownDragCaretRect;

    RetainPtr<NSMutableDictionary<NSNumber *, NSValue *>>_remainingAdditionalItemRequestLocationsByProgress;
    RetainPtr<NSMutableArray<NSValue *>>_queuedAdditionalItemRequestLocations;
    RetainPtr<NSMutableArray> _liftPreviews;
    RetainPtr<NSMutableArray<UITargetedDragPreview *>> _cancellationPreviews;
    RetainPtr<NSMutableArray> _dropPreviews;
    RetainPtr<NSMutableArray> _delayedDropPreviews;
    RetainPtr<NSMutableArray> _defaultDropPreviewsForExternalItems;

    RetainPtr<NSMutableArray<_WKAttachment *>> _insertedAttachments;
    RetainPtr<NSMutableArray<_WKAttachment *>> _removedAttachments;

    bool _hasStartedInputSession;
    double _currentProgress;
    bool _isDoneWithCurrentRun;
    bool _isDoneWaitingForDelayedDropPreviews;
    DragAndDropPhase _phase;

    RetainPtr<UIDropProposal> _lastKnownDropProposal;

    BlockPtr<BOOL(_WKActivatedElementInfo *)> _showCustomActionSheetBlock;
    BlockPtr<NSArray *(NSItemProvider *, NSArray *, NSDictionary *)> _convertItemProvidersBlock;
    BlockPtr<NSArray *(id <UIDropSession>)> _overridePerformDropBlock;
    BlockPtr<UIDropOperation(UIDropOperation, id)> _overrideDragUpdateBlock;
    BlockPtr<void(BOOL, NSArray *)> _dropCompletionBlock;
    BlockPtr<void()> _sessionWillBeginBlock;
    Vector<BlockPtr<void(UIViewAnimatingPosition)>> _dropAnimationCompletionBlocks;
}

- (instancetype)initWithWebViewFrame:(CGRect)frame
{
    return [self initWithWebViewFrame:frame configuration:nil];
}

- (instancetype)initWithWebViewFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
{
    if (configuration)
        return [self initWithWebView:[[[TestWKWebView alloc] initWithFrame:frame configuration:configuration] autorelease]];

    return [self initWithWebView:[[[TestWKWebView alloc] initWithFrame:frame] autorelease]];
}

- (instancetype)initWithWebView:(TestWKWebView *)webView
{
    if (self = [super init]) {
        _webView = webView;
        _shouldEnsureUIApplication = NO;
        _shouldBecomeFirstResponder = YES;
        _shouldAllowMoveOperation = YES;
        _dropAnimationTiming = DropAnimationShouldFinishAfterHandlingDrop;
        [_webView setUIDelegate:self];
        [_webView _setInputDelegate:self];
        self.dragDestinationAction = WKDragDestinationActionAny & ~WKDragDestinationActionLoad;
    }
    return self;
}

- (void)dealloc
{
    if ([_webView UIDelegate] == self)
        [_webView setUIDelegate:nil];

    if ([_webView _inputDelegate] == self)
        [_webView _setInputDelegate:nil];

    [super dealloc];
}

- (void)_resetSimulatedState
{
    _phase = DragAndDropPhaseBeginning;
    _currentProgress = 0;
    _isDoneWithCurrentRun = false;
    _isDoneWaitingForDelayedDropPreviews = true;
    _observedEventNames = adoptNS([[NSMutableArray alloc] init]);
    _insertedAttachments = adoptNS([[NSMutableArray alloc] init]);
    _removedAttachments = adoptNS([[NSMutableArray alloc] init]);
    _finalSelectionStartRect = CGRectNull;
    _dragSession = nil;
    _dropSession = nil;
    _lastKnownDropProposal = nil;
    _lastKnownDragCaretRect = CGRectZero;
    _remainingAdditionalItemRequestLocationsByProgress = nil;
    _queuedAdditionalItemRequestLocations = adoptNS([[NSMutableArray alloc] init]);
    _liftPreviews = adoptNS([[NSMutableArray alloc] init]);
    _dropPreviews = adoptNS([[NSMutableArray alloc] init]);
    _cancellationPreviews = adoptNS([[NSMutableArray alloc] init]);
    _delayedDropPreviews = adoptNS([[NSMutableArray alloc] init]);
    _hasStartedInputSession = false;
}

- (NSArray *)observedEventNames
{
    return _observedEventNames.get();
}

- (UIDropProposal *)lastKnownDropProposal
{
    return _lastKnownDropProposal.get();
}

- (void)simulateAllTouchesCanceled:(NSNotification *)notification
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_advanceProgress) object:nil];
    _phase = DragAndDropPhaseCancelled;
    _currentProgress = 1;
    _isDoneWithCurrentRun = true;
    if (_dragSession)
        [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] session:_dragSession.get() didEndWithOperation:UIDropOperationCancel];
}

- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation
{
    [self runFrom:startLocation to:endLocation additionalItemRequestLocations:nil];
}

- (void)runFrom:(CGPoint)startLocation to:(CGPoint)endLocation additionalItemRequestLocations:(ProgressToCGPointValueMap)additionalItemRequestLocations
{
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter addObserver:self selector:@selector(simulateAllTouchesCanceled:) name:TestWebKitAPISimulateCancelAllTouchesNotificationName object:nil];

    if (_shouldEnsureUIApplication)
        UIApplicationInstantiateSingleton([DragAndDropSimulatorApplication class]);

    if (_shouldBecomeFirstResponder)
        [_webView becomeFirstResponder];

    [self _resetSimulatedState];

    if (additionalItemRequestLocations)
        _remainingAdditionalItemRequestLocationsByProgress = adoptNS([additionalItemRequestLocations mutableCopy]);

    for (NSString *eventName in dragAndDropEventNames()) {
        [_webView performAfterReceivingMessage:eventName action:[strongSelf = retainPtr(self), name = retainPtr(eventName)] {
            [strongSelf->_observedEventNames addObject:name.get()];
        }];
    }

    _startLocation = startLocation;
    _endLocation = endLocation;

    if (self.externalItemProviders.count) {
        _dropSession = adoptNS([[MockDropSession alloc] initWithProviders:self.externalItemProviders location:_startLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]);
        _phase = DragAndDropPhaseBegan;
        [self _advanceProgress];
    } else {
        _dragSession = adoptNS([[MockDragSession alloc] initWithWindow:[_webView window] allowMove:self.shouldAllowMoveOperation]);
        [_dragSession setMockLocationInWindow:_startLocation];
        [(id <UIDragInteractionDelegate_ForWebKitOnly>)[_webView dragInteractionDelegate] _dragInteraction:[_webView dragInteraction] prepareForSession:_dragSession.get() completion:[strongSelf = retainPtr(self)] {
            if (strongSelf->_phase == DragAndDropPhaseCancelled)
                return;

            strongSelf->_phase = DragAndDropPhaseBeginning;
            [strongSelf _advanceProgress];
        }];
    }

    Util::run(&_isDoneWithCurrentRun);
    Util::run(&_isDoneWaitingForDelayedDropPreviews);
    [_webView clearMessageHandlers:dragAndDropEventNames()];
    [_webView waitForNextPresentationUpdate];

    auto contentView = [_webView textInputContentView];
    _finalSelectionStartRect = [contentView caretRectForPosition:contentView.selectedTextRange.start];

    [defaultCenter removeObserver:self];
}

- (void)_concludeDropAndPerformOperationIfNecessary
{
    _lastKnownDragCaretRect = [_webView _dragCaretRect];
    auto operation = [_lastKnownDropProposal operation];
    if (operation != UIDropOperationCancel && operation != UIDropOperationForbidden) {
        NSInteger dropPreviewIndex = 0;
        __block NSUInteger numberOfPendingPreviews = [_dropSession items].count;
        _isDoneWaitingForDelayedDropPreviews = !numberOfPendingPreviews;
        BOOL canUseDefaultDropPreviewsForExternalItems = [_defaultDropPreviewsForExternalItems count] == [_dropSession items].count;
        for (UIDragItem *item in [_dropSession items]) {
            RetainPtr<UITargetedDragPreview> defaultPreview;
            if (canUseDefaultDropPreviewsForExternalItems)
                defaultPreview = [_defaultDropPreviewsForExternalItems objectAtIndex:dropPreviewIndex];
            else {
                // Just fall back to an arbitrary non-null drag preview if the test didn't specify one.
                defaultPreview = adoptNS([[UITargetedDragPreview alloc] initWithView:_webView.get()]);
            }

            id <UIDropInteractionDelegate_Staging_31075005> delegate = (id <UIDropInteractionDelegate_Staging_31075005>)[_webView dropInteractionDelegate];
            UIDropInteraction *interaction = [_webView dropInteraction];
            [_dropPreviews addObject:[delegate dropInteraction:interaction previewForDroppingItem:item withDefault:defaultPreview.get()] ?: NSNull.null];
            [_delayedDropPreviews addObject:NSNull.null];
            [delegate _dropInteraction:interaction delayedPreviewProviderForDroppingItem:item previewProvider:^(UITargetedDragPreview *preview) {
                if (preview)
                    [_delayedDropPreviews setObject:preview atIndexedSubscript:dropPreviewIndex];

                if (!--numberOfPendingPreviews)
                    _isDoneWaitingForDelayedDropPreviews = true;
            }];
            ++dropPreviewIndex;
        }
        [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] performDrop:_dropSession.get()];
        _phase = DragAndDropPhasePerformingDrop;

        for (UIDragItem *item in [_dropSession items])
            [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] item:item willAnimateDropWithAnimator:self];

        if (_dropAnimationTiming == DropAnimationShouldFinishBeforeHandlingDrop) {
            [_webView evaluateJavaScript:@"" completionHandler:^(id, NSError *) {
                // We need to at least ensure one round trip to the web process and back, to ensure that the UI process will have received any image placeholders
                // that were just inserted as a result of performing the drop. However, this is guaranteed to run before the UI process receives the drop completion
                // message, since item provider loading is asynchronous.
                [self _invokeDropAnimationCompletionBlocksAndConcludeDrop];
            }];
        }
    } else {
        _isDoneWithCurrentRun = true;
        _phase = DragAndDropPhaseCancelled;
        [[_dropSession items] enumerateObjectsUsingBlock:^(UIDragItem *item, NSUInteger index, BOOL *) {
            UITargetedDragPreview *defaultPreview = nil;
            if ([_liftPreviews count] && [[_liftPreviews objectAtIndex:index] isEqual:NSNull.null])
                defaultPreview = [_liftPreviews objectAtIndex:index];

            UITargetedDragPreview *preview = [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] previewForCancellingItem:item withDefault:defaultPreview];
            if (preview)
                [_cancellationPreviews addObject:preview];
        }];
        [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] concludeDrop:_dropSession.get()];
    }

    [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidEnd:_dropSession.get()];

    if (_dragSession) {
        auto delegate = [_webView dragInteractionDelegate];
        [delegate dragInteraction:[_webView dragInteraction] session:_dragSession.get() didEndWithOperation:operation];
        if ([delegate respondsToSelector:@selector(_clearToken:)])
            [(id <UITextInputMultiDocument>)delegate _clearToken:nil];
        [_webView becomeFirstResponder];
    }
}

- (void)_enqueuePendingAdditionalItemRequestLocations
{
    NSMutableArray *progressValuesToRemove = [NSMutableArray array];
    for (NSNumber *progressValue in _remainingAdditionalItemRequestLocationsByProgress.get()) {
        double progress = progressValue.doubleValue;
        if (progress > _currentProgress)
            continue;
        [progressValuesToRemove addObject:progressValue];
        [_queuedAdditionalItemRequestLocations addObject:[_remainingAdditionalItemRequestLocationsByProgress objectForKey:progressValue]];
    }

    for (NSNumber *progressToRemove in progressValuesToRemove)
        [_remainingAdditionalItemRequestLocationsByProgress removeObjectForKey:progressToRemove];
}

- (BOOL)_sendQueuedAdditionalItemRequest
{
    if (![_queuedAdditionalItemRequestLocations count])
        return NO;

    RetainPtr<NSValue> requestLocationValue = [_queuedAdditionalItemRequestLocations objectAtIndex:0];
    [_queuedAdditionalItemRequestLocations removeObjectAtIndex:0];

    auto requestLocation = [[_webView window] convertPoint:[requestLocationValue CGPointValue] toView:_webView.get()];
    [(id <UIDragInteractionDelegate_ForWebKitOnly>)[_webView dragInteractionDelegate] _dragInteraction:[_webView dragInteraction] itemsForAddingToSession:_dragSession.get() withTouchAtPoint:requestLocation completion:[dragSession = _dragSession, dropSession = _dropSession] (NSArray *items) {
        [dragSession addItems:items];
        [dropSession addItems:items];
    }];
    return YES;
}

- (void)_advanceProgress
{
    [self _enqueuePendingAdditionalItemRequestLocations];
    if ([self _sendQueuedAdditionalItemRequest]) {
        [self _scheduleAdvanceProgress];
        return;
    }

    _lastKnownDragCaretRect = [_webView _dragCaretRect];
    _currentProgress += progressIncrementStep;
    CGPoint locationInWindow = self._currentLocation;
    [_dragSession setMockLocationInWindow:locationInWindow];
    [_dropSession setMockLocationInWindow:locationInWindow];

    if (_currentProgress >= 1) {
        _currentProgress = 1;
        [self _concludeDropAndPerformOperationIfNecessary];
        return;
    }

    switch (_phase) {
    case DragAndDropPhaseBeginning: {
        NSMutableArray<NSItemProvider *> *itemProviders = [NSMutableArray array];
        NSArray *items = [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] itemsForBeginningSession:_dragSession.get()];
        if (!items.count) {
            _phase = DragAndDropPhaseCancelled;
            _currentProgress = 1;
            _isDoneWithCurrentRun = true;
            return;
        }

        for (UIDragItem *item in items) {
            [itemProviders addObject:item.itemProvider];
            UITargetedDragPreview *liftPreview = [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] previewForLiftingItem:item session:_dragSession.get()];
            EXPECT_TRUE(liftPreview || ![_webView window]);
            [_liftPreviews addObject:liftPreview ?: NSNull.null];
        }

        _dropSession = adoptNS([[MockDropSession alloc] initWithProviders:itemProviders location:self._currentLocation window:[_webView window] allowMove:self.shouldAllowMoveOperation]);
        [_dragSession setItems:items];
        _sourceItemProviders = itemProviders;
        if (self.showCustomActionSheetBlock) {
            // Defer progress until the custom action sheet is dismissed.
            auto startLocationInView = [[_webView window] convertPoint:_startLocation toView:_webView.get()];
            [_webView _simulateLongPressActionAtLocation:startLocationInView];
            return;
        }

        auto delegate = [_webView dragInteractionDelegate];
        if ([delegate respondsToSelector:@selector(_preserveFocusWithToken:destructively:)])
            [(id <UITextInputMultiDocument>)delegate _preserveFocusWithToken:nil destructively:NO];

        [_webView resignFirstResponder];

        [delegate dragInteraction:[_webView dragInteraction] sessionWillBegin:_dragSession.get()];

        RetainPtr<WKWebView> retainedWebView = _webView;
        dispatch_async(dispatch_get_main_queue(), ^() {
            [retainedWebView resignFirstResponder];
        });

        _phase = DragAndDropPhaseBegan;
        break;
    }
    case DragAndDropPhaseBegan:
        [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidEnter:_dropSession.get()];
        _phase = DragAndDropPhaseEntered;
        break;
    case DragAndDropPhaseEntered: {
        _lastKnownDropProposal = [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] sessionDidUpdate:_dropSession.get()];
        [_webView waitForNextPresentationUpdate];
        if (![self shouldAllowMoveOperation] && [_lastKnownDropProposal operation] == UIDropOperationMove)
            _lastKnownDropProposal = adoptNS([[UIDropProposal alloc] initWithDropOperation:UIDropOperationCancel]);
        break;
    }
    default:
        break;
    }

    [self _scheduleAdvanceProgress];
}

- (void)clearExternalDragInformation
{
    _externalItemProviders = nil;
    _defaultDropPreviewsForExternalItems = nil;
}

- (CGPoint)_currentLocation
{
    CGFloat distanceX = _endLocation.x - _startLocation.x;
    CGFloat distanceY = _endLocation.y - _startLocation.y;
    return CGPointMake(_startLocation.x + _currentProgress * distanceX, _startLocation.y + _currentProgress * distanceY);
}

- (void)_scheduleAdvanceProgress
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_advanceProgress) object:nil];
    [self performSelector:@selector(_advanceProgress) withObject:nil afterDelay:progressTimeStep];
}

- (NSArray *)sourceItemProviders
{
    return _sourceItemProviders.get();
}

- (NSArray *)externalItemProviders
{
    return _externalItemProviders.get();
}

- (void)setExternalItemProviders:(NSArray *)externalItemProviders
{
    _externalItemProviders = adoptNS([externalItemProviders copy]);
}

- (void)setExternalItemProviders:(NSArray<NSItemProvider *> *)itemProviders defaultDropPreviews:(NSArray<UITargetedDragPreview *> *)previews
{
    ASSERT(itemProviders.count == previews.count);
    self.externalItemProviders = itemProviders;
    _defaultDropPreviewsForExternalItems = adoptNS(previews.copy);
}

- (DragAndDropPhase)phase
{
    return _phase;
}

- (NSArray *)liftPreviews
{
    return _liftPreviews.get();
}

- (NSArray<UITargetedDragPreview *> *)cancellationPreviews
{
    return _cancellationPreviews.get();
}

- (NSArray<UITargetedDragPreview *> *)dropPreviews
{
    return _dropPreviews.get();
}

- (NSArray<UITargetedDragPreview *> *)delayedDropPreviews
{
    return _delayedDropPreviews.get();
}

- (CGRect)lastKnownDragCaretRect
{
    return _lastKnownDragCaretRect;
}

- (void)ensureInputSession
{
    Util::run(&_hasStartedInputSession);
}

- (NSArray<_WKAttachment *> *)insertedAttachments
{
    return _insertedAttachments.get();
}

- (NSArray<_WKAttachment *> *)removedAttachments
{
    return _removedAttachments.get();
}

- (void)endDataTransfer
{
    [[_webView dragInteractionDelegate] dragInteraction:[_webView dragInteraction] sessionDidTransferItems:_dragSession.get()];
}

- (TestWKWebView *)webView
{
    return _webView.get();
}

- (void)setShowCustomActionSheetBlock:(BOOL(^)(_WKActivatedElementInfo *))showCustomActionSheetBlock
{
    _showCustomActionSheetBlock = showCustomActionSheetBlock;
}

- (BOOL(^)(_WKActivatedElementInfo *))showCustomActionSheetBlock
{
    return _showCustomActionSheetBlock.get();
}

- (void)setConvertItemProvidersBlock:(NSArray *(^)(NSItemProvider *, NSArray *, NSDictionary *))convertItemProvidersBlock
{
    _convertItemProvidersBlock = convertItemProvidersBlock;
}

- (NSArray *(^)(NSItemProvider *, NSArray *, NSDictionary *))convertItemProvidersBlock
{
    return _convertItemProvidersBlock.get();
}

- (void)setOverridePerformDropBlock:(NSArray *(^)(id <UIDropSession>))overridePerformDropBlock
{
    _overridePerformDropBlock = overridePerformDropBlock;
}

- (NSArray *(^)(id <UIDropSession>))overridePerformDropBlock
{
    return _overridePerformDropBlock.get();
}

- (void)setOverrideDragUpdateBlock:(UIDropOperation(^)(UIDropOperation, id <UIDropSession>))overrideDragUpdateBlock
{
    _overrideDragUpdateBlock = overrideDragUpdateBlock;
}

- (UIDropOperation(^)(UIDropOperation, id <UIDropSession>))overrideDragUpdateBlock
{
    return _overrideDragUpdateBlock.get();
}

- (void)setDropCompletionBlock:(void(^)(BOOL, NSArray *))dropCompletionBlock
{
    _dropCompletionBlock = dropCompletionBlock;
}

- (void(^)(BOOL, NSArray *))dropCompletionBlock
{
    return _dropCompletionBlock.get();
}

- (void)setSessionWillBeginBlock:(dispatch_block_t)block
{
    _sessionWillBeginBlock = block;
}

- (dispatch_block_t)sessionWillBeginBlock
{
    return _sessionWillBeginBlock.get();
}

- (void)addAnimations:(void (^)())animations
{
    // This is not implemented by the drag-and-drop simulator yet, since WebKit doesn't make use of
    // "alongside" animations during drop.
    ASSERT_NOT_REACHED();
}

- (void)addCompletion:(void (^)(UIViewAnimatingPosition))completion
{
    _dropAnimationCompletionBlocks.append(makeBlockPtr(completion));
}

- (void)_invokeDropAnimationCompletionBlocksAndConcludeDrop
{
    for (auto block : std::exchange(_dropAnimationCompletionBlocks, { }))
        block(UIViewAnimatingPositionEnd);
    [[_webView dropInteractionDelegate] dropInteraction:[_webView dropInteraction] concludeDrop:_dropSession.get()];
}

#pragma mark - WKUIDelegatePrivate

- (void)_webView:(WKWebView *)webView dataInteraction:(UIDragInteraction *)interaction sessionWillBegin:(id <UIDragSession>)session
{
    if (_sessionWillBeginBlock)
        _sessionWillBeginBlock();
}

- (void)_webView:(WKWebView *)webView dataInteractionOperationWasHandled:(BOOL)handled forSession:(id)session itemProviders:(NSArray<NSItemProvider *> *)itemProviders
{
    if (self.dropCompletionBlock)
        self.dropCompletionBlock(handled, itemProviders);

    if (_dropAnimationTiming == DropAnimationShouldFinishBeforeHandlingDrop) {
        _isDoneWithCurrentRun = true;
        return;
    }

    [_webView _doAfterReceivingEditDragSnapshotForTesting:^{
        [self _invokeDropAnimationCompletionBlocksAndConcludeDrop];
        _isDoneWithCurrentRun = true;
    }];
}

- (UIDropProposal *)_webView:(WKWebView *)webView willUpdateDropProposalToProposal:(UIDropProposal *)proposal forSession:(id <UIDropSession>)session
{
    if (!self.overrideDragUpdateBlock)
        return proposal;

    return [[[UIDropProposal alloc] initWithDropOperation:self.overrideDragUpdateBlock(proposal.operation, session)] autorelease];
}

- (NSArray *)_webView:(WKWebView *)webView adjustedDataInteractionItemProvidersForItemProvider:(NSItemProvider *)itemProvider representingObjects:(NSArray *)representingObjects additionalData:(NSDictionary *)additionalData
{
    return self.convertItemProvidersBlock ? self.convertItemProvidersBlock(itemProvider, representingObjects, additionalData) : @[ itemProvider ];
}

IGNORE_WARNINGS_BEGIN("deprecated-implementations")
- (BOOL)_webView:(WKWebView *)webView showCustomSheetForElement:(_WKActivatedElementInfo *)element
IGNORE_WARNINGS_END
{
    if (!self.showCustomActionSheetBlock)
        return NO;

    dispatch_async(dispatch_get_main_queue(), [strongSelf = retainPtr(self)] {
        [[strongSelf->_webView dragInteractionDelegate] dragInteraction:[strongSelf->_webView dragInteraction] sessionWillBegin:strongSelf->_dragSession.get()];
        strongSelf->_phase = DragAndDropPhaseBegan;
        [strongSelf _scheduleAdvanceProgress];
    });

    return self.showCustomActionSheetBlock(element);
}

- (NSArray<UIDragItem *> *)_webView:(WKWebView *)webView willPerformDropWithSession:(id <UIDropSession>)session
{
    return self.overridePerformDropBlock ? self.overridePerformDropBlock(session) : session.items;
}

- (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment withSource:(NSString *)source
{
    [_insertedAttachments addObject:attachment];
}

- (void)_webView:(WKWebView *)webView didRemoveAttachment:(_WKAttachment *)attachment
{
    [_removedAttachments addObject:attachment];
}

- (WKDragDestinationAction)_webView:(WKWebView *)webView dragDestinationActionMaskForDraggingInfo:(id)draggingInfo
{
    return self.dragDestinationAction;
}

#pragma mark - _WKInputDelegate

- (BOOL)_webView:(WKWebView *)webView focusShouldStartInputSession:(id <_WKFocusedElementInfo>)info
{
    return _allowsFocusToStartInputSession;
}

- (void)_webView:(WKWebView *)webView didStartInputSession:(id <_WKFormInputSession>)inputSession
{
    _hasStartedInputSession = true;
}

@end

#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(IOS_FAMILY)
