/*
 * 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()]];
#elif PLATFORM(IOS)
    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"]);
}
