/*
 * Copyright (C) 2019 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 "PlatformUtilities.h"
#import "TestWKWebView.h"
#import "UIKitSPI.h"
#import <CoreServices/CoreServices.h>
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/_WKExperimentalFeature.h>

@interface TestWKWebView (ClipboardTests)

- (void)readClipboard;

@end

@implementation TestWKWebView (ClipboardTests)

- (void)readClipboard
{
    __block bool done = false;
    [self performAfterReceivingMessage:@"readClipboard" action:^{
        done = true;
    }];
    [self evaluateJavaScript:@"readClipboard()" completionHandler:nil];
    TestWebKitAPI::Util::run(&done);
}

@end

static RetainPtr<TestWKWebView> createWebViewForClipboardTests()
{
#if PLATFORM(IOS_FAMILY)
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // UIPasteboard's type coercion codepaths only take effect when the UIApplication has been initialized.
        UIApplicationInitialize();
    });
#endif // PLATFORM(IOS_FAMILY)

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [[configuration preferences] _setDOMPasteAllowed:YES];
    [[configuration preferences] _setJavaScriptCanAccessClipboard:YES];
    for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) {
        if ([feature.key isEqualToString:@"AsyncClipboardAPIEnabled"]) {
            [[configuration preferences] _setEnabled:YES forExperimentalFeature:feature];
            break;
        }
    }

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]);
    [webView synchronouslyLoadTestPageNamed:@"clipboard"];
    return webView;
}

static void writeMultipleObjectsToPlatformPasteboard()
{
#if PLATFORM(MAC)
    auto firstItem = adoptNS([[NSPasteboardItem alloc] init]);
    [firstItem setString:@"Hello" forType:NSPasteboardTypeString];

    auto secondItem = adoptNS([[NSPasteboardItem alloc] init]);
    [secondItem setString:@"https://apple.com/" forType:NSPasteboardTypeURL];

    auto thirdItem = adoptNS([[NSPasteboardItem alloc] init]);
    [thirdItem setString:@"<strong style='color: rgb(0, 255, 0);'>Hello world</strong>" forType:NSPasteboardTypeHTML];

    auto fourthItem = adoptNS([[NSPasteboardItem alloc] init]);
    [fourthItem setString:@"WebKit" forType:NSPasteboardTypeString];
    [fourthItem setString:@"https://webkit.org/" forType:NSPasteboardTypeURL];
    [fourthItem setString:@"<a href='https://webkit.org/'>Hello world</a>" forType:NSPasteboardTypeHTML];

    NSPasteboard *pasteboard = NSPasteboard.generalPasteboard;
    [pasteboard clearContents];
    [pasteboard writeObjects:@[firstItem.get(), secondItem.get(), thirdItem.get(), fourthItem.get()]];
#else
    auto firstItem = adoptNS([[NSItemProvider alloc] initWithObject:@"Hello"]);
    auto secondItem = adoptNS([[NSItemProvider alloc] initWithObject:[NSURL URLWithString:@"https://apple.com/"]]);
    auto thirdItem = adoptNS([[NSItemProvider alloc] init]);
    [thirdItem registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeHTML visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[&] (void (^completionHandler)(NSData *, NSError *)) -> NSProgress * {
        completionHandler([@"<strong style='color: rgb(0, 255, 0);'>Hello world</strong>" dataUsingEncoding:NSUTF8StringEncoding], nil);
        return nil;
    }];

    auto fourthItem = adoptNS([[NSItemProvider alloc] init]);
    [fourthItem registerObject:@"WebKit" visibility:NSItemProviderRepresentationVisibilityAll];
    [fourthItem registerObject:[NSURL URLWithString:@"https://webkit.org/"] visibility:NSItemProviderRepresentationVisibilityAll];
    [fourthItem registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeHTML visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[&] (void (^completionHandler)(NSData *, NSError *)) -> NSProgress * {
        completionHandler([@"<a href='https://webkit.org/'>Hello world</a>" dataUsingEncoding:NSUTF8StringEncoding], nil);
        return nil;
    }];

    UIPasteboard.generalPasteboard.itemProviders = @[ firstItem.get(), secondItem.get(), thirdItem.get(), fourthItem.get() ];
#endif
}

TEST(ClipboardTests, ReadMultipleItems)
{
    auto webView = createWebViewForClipboardTests();
    writeMultipleObjectsToPlatformPasteboard();
    [webView readClipboard];

    EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"exception ? exception.message : ''"]);
    EXPECT_EQ(4U, [[webView objectByEvaluatingJavaScript:@"clipboardData.length"] unsignedIntValue]);
    EXPECT_WK_STREQ("Hello", [webView stringByEvaluatingJavaScript:@"clipboardData[0]['text/plain']"]);
    EXPECT_WK_STREQ("https://apple.com/", [webView stringByEvaluatingJavaScript:@"clipboardData[1]['text/uri-list']"]);
    EXPECT_WK_STREQ("rgb(0, 255, 0)", [webView stringByEvaluatingJavaScript:@"getComputedStyle(clipboardData[2]['text/html'].querySelector('strong')).color"]);
    EXPECT_WK_STREQ("WebKit", [webView stringByEvaluatingJavaScript:@"clipboardData[3]['text/plain']"]);
    EXPECT_WK_STREQ("https://webkit.org/", [webView objectByEvaluatingJavaScript:@"clipboardData[3]['text/uri-list']"]);
    EXPECT_WK_STREQ("https://webkit.org/", [webView stringByEvaluatingJavaScript:@"clipboardData[3]['text/html'].querySelector('a').href"]);
}
