/*
 * Copyright (C) 2005-2018 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 "DumpRenderTreeDraggingInfo.h"

#if !PLATFORM(IOS_FAMILY)

#import "AppKitTestSPI.h"
#import "DumpRenderTree.h"
#import "DumpRenderTreeFileDraggingSource.h"
#import "DumpRenderTreePasteboard.h"
#import "EventSendingController.h"
#import <wtf/RetainPtr.h>

@interface DumpRenderTreeFilePromiseReceiver : NSFilePromiseReceiver {
    RetainPtr<NSArray<NSString *>> _promisedUTIs;
    RetainPtr<NSMutableArray<NSURL *>> _destinationURLs;
    DumpRenderTreeFileDraggingSource *_draggingSource;
}

- (instancetype)initWithPromisedUTIs:(NSArray<NSString *> *)promisedUTIs;

@property (nonatomic, retain) DumpRenderTreeFileDraggingSource *draggingSource;

@end

@implementation DumpRenderTreeFilePromiseReceiver

@synthesize draggingSource=_draggingSource;

- (instancetype)initWithPromisedUTIs:(NSArray<NSString *> *)promisedUTIs
{
    if (!(self = [super init]))
        return nil;

    _promisedUTIs = adoptNS([promisedUTIs copy]);
    _destinationURLs = adoptNS([NSMutableArray new]);
    return self;
}

- (NSArray<NSString *> *)fileTypes
{
    return _promisedUTIs.get();
}

- (NSArray<NSString *> *)fileNames
{
    NSMutableArray *fileNames = [NSMutableArray arrayWithCapacity:[_destinationURLs count]];
    for (NSURL *url in _destinationURLs.get())
        [fileNames addObject:url.lastPathComponent];
    return fileNames;
}

- (void)dealloc
{
    // WebKit does not delete promised files it receives into NSTemporaryDirectory() (it should!),
    // so we need to. Failing to do so could result in unpredictable file names in a subsequent test
    // that promises a file with the same name as one of these destination URLs.

    for (NSURL *destinationURL in _destinationURLs.get()) {
        assert([destinationURL.path hasPrefix:NSTemporaryDirectory()]);
        [NSFileManager.defaultManager removeItemAtURL:destinationURL error:nil];
    }

    [_draggingSource release];
    [super dealloc];
}

static std::pair<NSURL *, NSError *> copyFile(NSURL *sourceURL, NSURL *destinationDirectory)
{
    // Emulate how CFPasteboard finds unique destination file names by inserting " 2", " 3", and so
    // on between the file name's base and extension until a new file is successfully created in
    // the destination directory.

    NSUInteger number = 2;
    NSString *fileName = sourceURL.lastPathComponent;
    NSURL *destinationURL = [NSURL fileURLWithPath:fileName relativeToURL:destinationDirectory];
    NSError *error;
    while (![NSFileManager.defaultManager copyItemAtURL:sourceURL toURL:destinationURL error:&error]) {
        if (error.domain != NSCocoaErrorDomain || error.code != NSFileWriteFileExistsError)
            return { nil, error };

        NSString *newFileName = [NSString stringWithFormat:@"%@ %lu.%@", fileName.stringByDeletingPathExtension, (unsigned long)number++, fileName.pathExtension];
        destinationURL = [NSURL fileURLWithPath:newFileName relativeToURL:destinationDirectory];
    }

    return { destinationURL, nil };
}

- (void)receivePromisedFilesAtDestination:(NSURL *)destinationDirectory options:(NSDictionary *)options operationQueue:(NSOperationQueue *)operationQueue reader:(void (^)(NSURL *fileURL, NSError * __nullable errorOrNil))reader
{
    // Layout tests need files to be received in a predictable order, so execute operations in serial.
    operationQueue.maxConcurrentOperationCount = 1;

    NSArray<NSURL *> *sourceURLs = _draggingSource.promisedFileURLs;
    for (NSURL *sourceURL in sourceURLs) {
        [operationQueue addOperationWithBlock:^{
            NSError *error;
            NSURL *destinationURL;
            std::tie(destinationURL, error) = copyFile(sourceURL, destinationDirectory);
            if (destinationURL) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [_destinationURLs addObject:destinationURL];
                });
            }

            reader(destinationURL, error);
        }];
    }
}

@end

@implementation DumpRenderTreeDraggingInfo

- (id)initWithImage:(NSImage *)anImage offset:(NSSize)o pasteboard:(NSPasteboard *)pboard source:(id)source
{
    draggedImage = [anImage retain];
    draggingPasteboard = [pboard retain];
    draggingSource = [source retain];
    offset = o;
    
    return [super init];
}

- (void)dealloc
{
    [draggedImage release];
    [draggingPasteboard release];
    [draggingSource release];
    [super dealloc];
}

- (NSWindow *)draggingDestinationWindow 
{
    return [[mainFrame webView] window];
}

- (NSDragOperation)draggingSourceOperationMask 
{
    return [draggingSource draggingSourceOperationMaskForLocal:YES];
}

- (NSPoint)draggingLocation
{ 
    return lastMousePosition; 
}

- (NSPoint)draggedImageLocation 
{
    return NSMakePoint(lastMousePosition.x + offset.width, lastMousePosition.y + offset.height);
}

- (NSImage *)draggedImage
{
    return draggedImage;
}

- (NSPasteboard *)draggingPasteboard
{
    return draggingPasteboard;
}

- (id)draggingSource
{
    return draggingSource;
}

- (int)draggingSequenceNumber
{
    NSLog(@"DumpRenderTree doesn't support draggingSequenceNumber");
    return 0;
}

- (void)slideDraggedImageTo:(NSPoint)screenPoint
{
    NSLog(@"DumpRenderTree doesn't support slideDraggedImageTo:");
}

- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
{
    NSLog(@"DumpRenderTree doesn't support namesOfPromisedFilesDroppedAtDestination:");
    return nil;
}

- (NSDraggingFormation)draggingFormation
{
    return NSDraggingFormationDefault;
}

- (void)setDraggingFormation:(NSDraggingFormation)formation
{
    // Ignored.
}

- (BOOL)animatesToDestination
{
    return NO;
}

- (void)setAnimatesToDestination:(BOOL)flag
{
    // Ignored.
}

- (NSInteger)numberOfValidItemsForDrop
{
    return 1;
}

- (void)setNumberOfValidItemsForDrop:(NSInteger)number
{
    // Ignored.
}

static NSMutableArray<NSFilePromiseReceiver *> *allFilePromiseReceivers()
{
    static NSMutableArray<NSFilePromiseReceiver *> *allReceivers = [[NSMutableArray alloc] init];
    return allReceivers;
}

+ (void)clearAllFilePromiseReceivers
{
    [allFilePromiseReceivers() removeAllObjects];
}

- (void)enumerateDraggingItemsWithOptions:(NSEnumerationOptions)enumOptions forView:(NSView *)view classes:(NSArray *)classArray searchOptions:(NSDictionary *)searchOptions usingBlock:(void (^)(NSDraggingItem *draggingItem, NSInteger idx, BOOL *stop))block
{
    assert(!enumOptions);
    assert(!searchOptions.count);

    BOOL stop = NO;
    for (Class classObject in classArray) {
        if (classObject != NSFilePromiseReceiver.class)
            continue;

        id promisedUTIs = [draggingPasteboard propertyListForType:NSFilesPromisePboardType];
        if (![promisedUTIs isKindOfClass:NSArray.class])
            return;

        for (id object in promisedUTIs) {
            if (![object isKindOfClass:NSString.class])
                return;
        }

        auto receiver = adoptNS([[DumpRenderTreeFilePromiseReceiver alloc] initWithPromisedUTIs:promisedUTIs]);
        [receiver setDraggingSource:draggingSource];
        [allFilePromiseReceivers() addObject:receiver.get()];

#if HAVE(NSDRAGGINGITEM_INITWITHITEM)
        auto item = adoptNS([[NSDraggingItem alloc] _initWithItem:receiver.get()]);
#else
        auto item = adoptNS([[NSDraggingItem alloc] initWithPasteboardWriter:(id <NSPasteboardWriting>)receiver.get()]); // FIXME: <https://webkit.org/b/194060> Pass an object of the right type.
        [item setItem:receiver.get()];
#endif

        block(item.get(), 0, &stop);
        if (stop)
            return;
    }
}

-(NSSpringLoadingHighlight)springLoadingHighlight
{
    return NSSpringLoadingHighlightNone;
}

- (void)resetSpringLoading
{
}

@end

#endif // !PLATFORM(IOS_FAMILY)
