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

#if PLATFORM(COCOA) && !PLATFORM(WATCHOS) && !PLATFORM(APPLETV)

#import "WKWebViewInternal.h"
#import "WebPageProxy.h"
#import <WebCore/ShareData.h>
#import <wtf/RetainPtr.h>
#import <wtf/WeakObjCPtr.h>

#if PLATFORM(IOS_FAMILY)
#import "UIKitSPI.h"
#import "WKContentViewInteraction.h"
#else
#import <pal/spi/mac/NSSharingServicePickerSPI.h>
#endif

#if PLATFORM(MAC)
@interface WKShareSheet () <NSSharingServiceDelegate, NSSharingServicePickerDelegate>
@end
#endif

@implementation WKShareSheet {
    WeakObjCPtr<WKWebView> _webView;
    WeakObjCPtr<id <WKShareSheetDelegate> > _delegate;
    WTF::CompletionHandler<void(bool)> _completionHandler;

#if PLATFORM(MAC)
    RetainPtr<NSSharingServicePicker> _sharingServicePicker;
#else
    RetainPtr<UIActivityViewController> _shareSheetViewController;
    RetainPtr<UIViewController> _presentationViewController;
#endif
}

- (id<WKShareSheetDelegate>)delegate
{
    return _delegate.get().get();
}

- (void)setDelegate:(id<WKShareSheetDelegate>)delegate
{
    _delegate = delegate;
}

- (instancetype)initWithView:(WKWebView *)view
{
    if (!(self = [super init]))
        return nil;

    _webView = view;

    return self;
}

- (void)presentWithParameters:(const WebCore::ShareDataWithParsedURL &)data inRect:(WTF::Optional<WebCore::FloatRect>)rect completionHandler:(WTF::CompletionHandler<void(bool)>&&)completionHandler
{
    auto shareDataArray = adoptNS([[NSMutableArray alloc] init]);
    
    if (!data.shareData.text.isEmpty())
        [shareDataArray addObject:(NSString *)data.shareData.text];
    
    if (data.url) {
        NSURL *url = (NSURL *)data.url.value();
#if PLATFORM(IOS_FAMILY)
        if (!data.shareData.title.isEmpty())
            url._title = data.shareData.title;
#endif
        [shareDataArray addObject:url];
    }
    
    if (!data.shareData.title.isEmpty() && ![shareDataArray count])
        [shareDataArray addObject:(NSString *)data.shareData.title];

    _completionHandler = WTFMove(completionHandler);

    if (auto resolution = [_webView _resolutionForShareSheetImmediateCompletionForTesting]) {
        [self _didCompleteWithSuccess:*resolution];
        [self dismiss];
        return;
    }
    
    WKWebView *webView = _webView.getAutoreleased();
    
#if PLATFORM(MAC)
    _sharingServicePicker = adoptNS([[NSSharingServicePicker alloc] initWithItems:shareDataArray.get()]);
    _sharingServicePicker.get().delegate = self;
    
    // WKShareSheet can be released under NSSharingServicePicker delegate callbacks.
    RetainPtr<WKShareSheet> protector(self);
    NSRect presentationRect;

    if (rect)
        presentationRect = *rect;
    else {
        NSPoint location = [NSEvent mouseLocation];
        NSRect mouseLocationRect = NSMakeRect(location.x, location.y, 1.0, 1.0);
        NSRect mouseLocationInWindow = [webView.window convertRectFromScreen:mouseLocationRect];
        presentationRect = [webView convertRect:mouseLocationInWindow fromView:nil];
    }
    [_sharingServicePicker showRelativeToRect:presentationRect ofView:webView preferredEdge:NSMinYEdge];
#else
    _shareSheetViewController = adoptNS([[UIActivityViewController alloc] initWithActivityItems:shareDataArray.get() applicationActivities:nil]);
    [_shareSheetViewController setCompletionWithItemsHandler:^(NSString *, BOOL completed, NSArray *, NSError *) {
        [self _didCompleteWithSuccess:completed];
        [self dispatchDidDismiss];
    }];
    
    UIPopoverPresentationController *popoverController = [_shareSheetViewController popoverPresentationController];
    if (rect) {
        popoverController.sourceView = webView;
        popoverController.sourceRect = *rect;
    } else
        popoverController._centersPopoverIfSourceViewNotSet = YES;
    
    _presentationViewController = [UIViewController _viewControllerForFullScreenPresentationFromView:webView];
    [_presentationViewController presentViewController:_shareSheetViewController.get() animated:YES completion:nil];
#endif
}

#if PLATFORM(MAC)
- (void)sharingServicePicker:(NSSharingServicePicker *)sharingServicePicker didChooseSharingService:(NSSharingService *)service
{
    if (service)
        return;

    [self _didCompleteWithSuccess:NO];
    [self dispatchDidDismiss];
}

- (id <NSSharingServiceDelegate>)sharingServicePicker:(NSSharingServicePicker *)sharingServicePicker delegateForSharingService:(NSSharingService *)sharingService
{
    return self;
}

- (NSWindow *)sharingService:(NSSharingService *)sharingService sourceWindowForShareItems:(NSArray *)items sharingContentScope:(NSSharingContentScope *)sharingContentScope
{
    return [_webView window];
}

- (void)sharingService:(NSSharingService *)sharingService didFailToShareItems:(NSArray *)items error:(NSError *)error
{
    [self _didCompleteWithSuccess:NO];
    [self dispatchDidDismiss];
}

- (void)sharingService:(NSSharingService *)sharingService didShareItems:(NSArray *)items
{
    [self _didCompleteWithSuccess:YES];
    [self dispatchDidDismiss];
}

#endif

- (void)_didCompleteWithSuccess:(BOOL)success
{
    auto completionHandler = WTFMove(_completionHandler);
    if (completionHandler)
        completionHandler(success);
}

- (void)dismiss
{
    // If programmatically dismissed without having already called the
    // completion handler, call it assuming failure.
    [self _didCompleteWithSuccess:NO];

#if PLATFORM(MAC)
    [_sharingServicePicker hide];
    [self dispatchDidDismiss];
#else
    if (!_presentationViewController)
        return;

    UIViewController *currentPresentedViewController = [_presentationViewController presentedViewController];
    if (currentPresentedViewController != _shareSheetViewController)
        return;

    [currentPresentedViewController dismissViewControllerAnimated:YES completion:^{
        [self dispatchDidDismiss];
        _presentationViewController = nil;
    }];
#endif
}

- (void)dispatchDidDismiss
{
    if ([_delegate respondsToSelector:@selector(shareSheetDidDismiss:)])
        [_delegate shareSheetDidDismiss:self];
}

@end

#endif // PLATFORM(COCOA) && !PLATFORM(WATCHOS) && !PLATFORM(APPLETV)
