/*
 * Copyright (C) 2015 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 "JavaScriptTest.h"
#import "Test.h"
#import "WebKitAgnosticTest.h"
#import <Carbon/Carbon.h>
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/WebViewPrivate.h>
#import <WebKit/WebPreferencesPrivate.h>
#import <wtf/RetainPtr.h>

@interface NSWindowController (WebKitFullScreenAdditions)
- (NSRect)initialFrame;
- (NSRect)finalFrame;
@end

static bool isWaitingForPageSignalToContinue = false;
static bool didGetPageSignalToContinue = false;

@interface FullscreenStateDelegate : NSObject <WebUIDelegate>
@end

@implementation FullscreenStateDelegate
- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
{
    EXPECT_TRUE(isWaitingForPageSignalToContinue);
    isWaitingForPageSignalToContinue = false;
    didGetPageSignalToContinue = true;
}
@end

// WebKit2 WKPageUIClient

static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo)
{
    EXPECT_TRUE(isWaitingForPageSignalToContinue);
    isWaitingForPageSignalToContinue = false;
    didGetPageSignalToContinue = true;
}

// WebKitAgnosticTest

namespace TestWebKitAPI {

class FullscreenZoomInitialFrame : public WebKitAgnosticTest {
public:
    template <typename View> void runTest(View);

    // WebKitAgnosticTest
    NSURL *url() const override { return [NSBundle.test_resourcesBundle URLForResource:@"FullscreenZoomInitialFrame" withExtension:@"html"]; }
    void didLoadURL(WebView *webView) override { runTest(webView); }
    void didLoadURL(WKWebView *wkView) override { runTest(wkView); }

    // Setup and teardown the UIDelegate which gets alert() signals from the page.
    void initializeView(WebView *) override;
    void initializeView(WKWebView *) override;
    void teardownView(WebView *) override;
    void teardownView(WKWebView *) override;

    void setPageScale(WebView *, double);
    void setPageScale(WKWebView *, double);
    void sendMouseDownEvent(WebView *, NSEvent *);
    void sendMouseDownEvent(WKWebView *, NSEvent *);

private:
    RetainPtr<id <WebUIDelegate>> m_delegate;
};

void FullscreenZoomInitialFrame::initializeView(WebView *webView)
{
    m_delegate = adoptNS([[FullscreenStateDelegate alloc] init]);
    webView.UIDelegate = m_delegate.get();

    RetainPtr<WebPreferences> customPreferences = adoptNS([[WebPreferences alloc] initWithIdentifier:@"FullscreenZoomInitialFramePreferences"]);
    [customPreferences setFullScreenEnabled:YES];
    webView.preferences = customPreferences.get();
}

void FullscreenZoomInitialFrame::teardownView(WebView *webView)
{
    EXPECT_TRUE(webView.UIDelegate == m_delegate.get());
    webView.UIDelegate = nil;
    m_delegate = nil;
}

void FullscreenZoomInitialFrame::initializeView(WKWebView *wkView)
{
    WKPageUIClientV0 uiClient;
    zeroBytes(uiClient);

    uiClient.base.version = 0;
    uiClient.runJavaScriptAlert = runJavaScriptAlert;

    WKPageSetPageUIClient(wkView._pageRefForTransitionToWKWebView, &uiClient.base);

    auto configuration = adoptWK(WKPageCopyPageConfiguration(wkView._pageRefForTransitionToWKWebView));
    auto preferences = WKPageConfigurationGetPreferences(configuration.get());
    WKPreferencesSetFullScreenEnabled(preferences, true);
}

void FullscreenZoomInitialFrame::teardownView(WKWebView *wkView)
{
    // We do not need to teardown the WKPageUIClient.
}

void FullscreenZoomInitialFrame::setPageScale(WebView *webView, double scale)
{
    [webView _scaleWebView:scale atOrigin:NSMakePoint(0, 0)];
}

void FullscreenZoomInitialFrame::setPageScale(WKWebView *wkView, double scale)
{
    WKPageSetScaleFactor(wkView._pageRefForTransitionToWKWebView, scale, WKPointMake(0, 0));
}

void FullscreenZoomInitialFrame::sendMouseDownEvent(WebView *webView, NSEvent *event)
{
    [webView.mainFrame.frameView.documentView mouseDown:event];
}

void FullscreenZoomInitialFrame::sendMouseDownEvent(WKWebView *wkView, NSEvent *event)
{
    [wkView mouseDown:event];
}

template <typename View>
void FullscreenZoomInitialFrame::runTest(View view)
{
    RetainPtr<NSWindow> window = adoptNS([[NSWindow alloc] initWithContentRect:view.frame styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO]);
    [window.get().contentView addSubview:view];
    [window makeKeyAndOrderFront:view];

    setPageScale(view, 2);

    NSEvent *event = [NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:NSMakePoint(5, 5) modifierFlags:0 timestamp:0 windowNumber:window.get().windowNumber context:0 eventNumber:0 clickCount:0 pressure:0];

    isWaitingForPageSignalToContinue = true;
    didGetPageSignalToContinue = false;
    sendMouseDownEvent(view, event);
    Util::run(&didGetPageSignalToContinue);

    id windowController = [[view window] windowController];
    EXPECT_TRUE([windowController respondsToSelector:@selector(initialFrame)]);
    EXPECT_TRUE([windowController respondsToSelector:@selector(finalFrame)]);

    NSRect initialFrame = [windowController initialFrame];
    NSRect finalFrame = [windowController finalFrame];

    EXPECT_EQ(300, initialFrame.size.width);
    EXPECT_EQ(300, initialFrame.size.height);
    EXPECT_EQ(view.bounds.size.width, finalFrame.size.width);
    EXPECT_EQ(view.bounds.size.height, finalFrame.size.height);

    isWaitingForPageSignalToContinue = true;
    didGetPageSignalToContinue = false;
    sendMouseDownEvent(view, event);
    Util::run(&didGetPageSignalToContinue);
}

TEST_F(FullscreenZoomInitialFrame, WebKit)
{
    runWebKit1Test();
}

// FIXME:<rdar://problem/20504403>
TEST_F(FullscreenZoomInitialFrame, DISABLED_WebKit2)
{
    runWebKit2Test();
}

} // namespace TestWebKitAPI
