/*
 * 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"

#if PLATFORM(MAC)

#import "PlatformUtilities.h"
#import "Test.h"
#import "TestNavigationDelegate.h"
#import "TestURLSchemeHandler.h"
#import "TestWKWebView.h"
#import <WebKit/WKUIDelegatePrivate.h>
#import <WebKit/WKURLSchemeHandler.h>
#import <WebKit/WKURLSchemeTaskPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WebKit.h>
#import <wtf/BlockPtr.h>
#import <wtf/HashMap.h>
#import <wtf/RetainPtr.h>
#import <wtf/RunLoop.h>
#import <wtf/Threading.h>
#import <wtf/Vector.h>
#import <wtf/text/StringHash.h>
#import <wtf/text/WTFString.h>

static RetainPtr<WKWebView> createdWebView;
static RetainPtr<TestNavigationDelegate> navDelegate;

@interface JavascriptURLNavigationDelegate : NSObject <WKUIDelegatePrivate>
@end
@implementation JavascriptURLNavigationDelegate

- (void)_webViewRunModal:(WKWebView *)webView
{
    EXPECT_EQ(webView, createdWebView.get());
}

- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
    createdWebView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [createdWebView setUIDelegate:self];

    navDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
    [navDelegate setDecidePolicyForNavigationAction:[&] (WKNavigationAction *action, void (^decisionHandler)(WKNavigationActionPolicy)) {
        decisionHandler(WKNavigationActionPolicyAllow);
    }];
    [createdWebView setNavigationDelegate:navDelegate.get()];

    return createdWebView.get();
}

- (void)_webViewClose:(WKWebView *)webView
{
    EXPECT_EQ(webView, createdWebView.get());
    [webView _close];
}

@end

static const char* mainResource = R"JSURLRESOURCE(
<body>
The initial frame should have "Hello there" in it.<br>
The second frame should not.<br>
<script>

function createURL(data, type = 'text/html') {
  return URL.createObjectURL(new Blob([data], {type: type}));
}

function waitForLoad() {
    showModalDialog(createURL(`
        <script>
        var dataURLDelay = 400;
        var earlyReturn = false;
        function tryIt() {
            if (earlyReturn)
                return;
            try {
                opener.frame.contentDocument.x;
            } catch (e) {
                earlyReturn = true;
                setTimeout(window.close, dataURLDelay * 1.5);
            }
        };
        setTimeout(tryIt, dataURLDelay);
        setTimeout(tryIt, dataURLDelay * 1.5);
        setTimeout(tryIt, dataURLDelay * 2);
        setTimeout(tryIt, dataURLDelay * 2.5);
        setTimeout(window.close, dataURLDelay * 3);
        </scrip` + 't>'
    ));
}

function runTest() {
    window.onmessage = null;

    frame = document.createElement('iframe');
    frame.src = location;
    document.body.appendChild(frame);

    frame.contentDocument.open();
    frame.contentWindow.addEventListener('readystatechange', () => {
        a = frame.contentDocument.createElement('a');
        a.href = targetURL;
        a.click();
        waitForLoad();
    }, {capture: true, once: true});

    var javascriptSource = `
    <script>
    alert(document.documentElement.outerHTML);
    function checkIt() {
        if (document.documentElement.outerHTML.includes('Hello worl' + 'd')) {
            console.log('Failed');
            if (window.webkit.messageHandlers && window.webkit.messageHandlers.testHandler)
                window.webkit.messageHandlers.testHandler.postMessage('Failed');
        } else {
            console.log('Passed');
            if (window.webkit.messageHandlers && window.webkit.messageHandlers.testHandler)
                window.webkit.messageHandlers.testHandler.postMessage('Passed');
        }
    }
    setTimeout(checkIt, 0);
    </scrip` + 't>';
    frame.src = 'javascript:"' + javascriptSource + '"';
}
window.onmessage = runTest;

var targetSource = `
<script>
function writeIt() {
    document.write('Hello world');
    parent.postMessage('go', '` + window.location.origin + `');
}
setTimeout(writeIt, 400);
</scrip` + 't>';

targetURL = 'data:text/html,' + targetSource;
loadedOnce = document.body.appendChild(document.createElement('iframe'));
loadedOnce.src = targetURL;
</script>
</body>
)JSURLRESOURCE";


TEST(WKWebView, JavascriptURLNavigation)
{
    static bool done;

    auto delegate = adoptNS([[JavascriptURLNavigationDelegate alloc] init]);
    auto handler = adoptNS([[TestURLSchemeHandler alloc] init]);
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"jsurl"];
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
    [webView setUIDelegate:delegate.get()];

    [webView performAfterReceivingMessage:@"Passed" action:^() {
        done = true;
    }];
    [webView performAfterReceivingMessage:@"Failed" action:^() {
        done = true;
        FAIL();
    }];

    [handler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {

        if (![task.request.URL.absoluteString isEqualToString:@"jsurl://host1/main.html"]) {
            // We only expect the URL above.
            FAIL();
        }

        auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil]);
        [task didReceiveResponse:response.get()];
        [task didReceiveData:[NSData dataWithBytes:mainResource length:strlen(mainResource)]];
        [task didFinish];
    }];

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"jsurl://host1/main.html"]]];

    TestWebKitAPI::Util::run(&done);
}

#endif // PLATFORM(MAC)
