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

#include "config.h"

#if PLATFORM(IOS_FAMILY)

#import "PlatformUtilities.h"
#import "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import "UIKitSPI.h"
#import <WebKit/WKWebViewPrivate.h>

@interface AsyncPolicyDelegateForInsetTest : NSObject<WKNavigationDelegate> {
    @public bool _navigationComplete;
}
@property (nonatomic, copy) void (^webContentProcessDidTerminate)(WKWebView *);
@end

@implementation AsyncPolicyDelegateForInsetTest

- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
{
    _navigationComplete = true;
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    int64_t deferredWaitTime = 100 * NSEC_PER_MSEC;
    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, deferredWaitTime);
    dispatch_after(when, dispatch_get_main_queue(), ^{
        decisionHandler(WKNavigationActionPolicyAllow);
    });
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    int64_t deferredWaitTime = 100 * NSEC_PER_MSEC;
    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, deferredWaitTime);
    dispatch_after(when, dispatch_get_main_queue(), ^{
        decisionHandler(WKNavigationResponsePolicyAllow);
    });
}

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
{
    if (_webContentProcessDidTerminate)
        _webContentProcessDidTerminate(webView);
}
@end

namespace TestWebKitAPI {

static const CGFloat viewHeight = 500;
static NSString *veryTallDocumentMarkup = @"<meta name='viewport' content='width=device-width, initial-scale=1'><body style='width: 100%; height: 5000px'>";

static void waitUntilInnerHeightIs(TestWKWebView *webView, CGFloat expectedValue)
{
    int tries = 0;
    do {
        Util::sleep(0.1);
    } while ([[webView objectByEvaluatingJavaScript:@"innerHeight"] floatValue] != expectedValue && ++tries <= 100);
}

TEST(ScrollViewInsetTests, InnerHeightWithLargeTopContentInset)
{
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, viewHeight)]);
    [webView scrollView].contentInset = UIEdgeInsetsMake(400, 0, 0, 0);
    [webView synchronouslyLoadHTMLString:veryTallDocumentMarkup];

    [webView stringByEvaluatingJavaScript:@"scrollTo(0, 10)"];
    waitUntilInnerHeightIs(webView.get(), viewHeight);
    EXPECT_EQ(viewHeight, [[webView objectByEvaluatingJavaScript:@"innerHeight"] floatValue]);
    EXPECT_EQ(10, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);

    [webView stringByEvaluatingJavaScript:@"scrollBy(0, -10)"];
    waitUntilInnerHeightIs(webView.get(), viewHeight);
    EXPECT_EQ(viewHeight, [[webView objectByEvaluatingJavaScript:@"innerHeight"] floatValue]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);

    [webView stringByEvaluatingJavaScript:@"scrollBy(0, 20)"];
    waitUntilInnerHeightIs(webView.get(), viewHeight);
    EXPECT_EQ(viewHeight, [[webView objectByEvaluatingJavaScript:@"innerHeight"] floatValue]);
    EXPECT_EQ(20, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);
}

TEST(ScrollViewInsetTests, InnerHeightWithLargeBottomContentInset)
{
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, viewHeight)]);
    [webView scrollView].contentInset = UIEdgeInsetsMake(0, 0, 400, 0);
    [webView synchronouslyLoadHTMLString:veryTallDocumentMarkup];
    [webView stringByEvaluatingJavaScript:@"scrollTo(0, 10)"];
    [webView waitForNextPresentationUpdate];
    EXPECT_EQ(viewHeight, [[webView objectByEvaluatingJavaScript:@"innerHeight"] floatValue]);
    EXPECT_EQ(10, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);

    [webView stringByEvaluatingJavaScript:@"scrollBy(0, -10)"];
    [webView waitForNextPresentationUpdate];
    EXPECT_EQ(viewHeight, [[webView objectByEvaluatingJavaScript:@"innerHeight"] floatValue]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);

    [webView stringByEvaluatingJavaScript:@"scrollBy(0, 20)"];
    [webView waitForNextPresentationUpdate];
    EXPECT_EQ(viewHeight, [[webView objectByEvaluatingJavaScript:@"innerHeight"] floatValue]);
    EXPECT_EQ(20, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);
}

TEST(ScrollViewInsetTests, RestoreInitialContentOffsetAfterNavigation)
{
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, viewHeight)]);
    [webView scrollView].contentInset = UIEdgeInsetsMake(400, 0, 0, 0);
    [webView synchronouslyLoadHTMLString:veryTallDocumentMarkup];
    [webView stringByEvaluatingJavaScript:@"scrollTo(0, 1000)"];
    [webView waitForNextPresentationUpdate];

    CGPoint contentOffsetAfterScrolling = [webView scrollView].contentOffset;
    EXPECT_EQ(0, contentOffsetAfterScrolling.x);
    EXPECT_EQ(1000, contentOffsetAfterScrolling.y);

    [webView synchronouslyLoadHTMLString:@"<body bgcolor='red'>"];
    [webView waitForNextPresentationUpdate];

    CGPoint contentOffsetAfterNavigation = [webView scrollView].contentOffset;
    EXPECT_EQ(0, contentOffsetAfterNavigation.x);
    EXPECT_EQ(-400, contentOffsetAfterNavigation.y);
}

TEST(ScrollViewInsetTests, RestoreInitialContentOffsetAfterCrash)
{
    auto delegate = adoptNS([[TestNavigationDelegate alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, viewHeight)]);
    [webView scrollView].contentInset = UIEdgeInsetsMake(400, 0, 0, 0);
    [webView synchronouslyLoadHTMLString:veryTallDocumentMarkup];
    [webView setNavigationDelegate:delegate.get()];

    CGPoint initialContentOffset = [webView scrollView].contentOffset;
    __block CGPoint contentOffsetAfterCrash = CGPointZero;
    __block bool done = false;
    [delegate setWebContentProcessDidTerminate:^(WKWebView *webView) {
        contentOffsetAfterCrash = webView.scrollView.contentOffset;
        done = true;
    }];

    [webView _killWebContentProcessAndResetState];
    Util::run(&done);

    EXPECT_EQ(initialContentOffset.x, contentOffsetAfterCrash.x);
    EXPECT_EQ(initialContentOffset.y, contentOffsetAfterCrash.y);
    EXPECT_EQ(0, initialContentOffset.x);
    EXPECT_EQ(-400, initialContentOffset.y);
}

TEST(ScrollViewInsetTests, RestoreInitialContentOffsetAfterCrashWithAsyncPolicyDelegates)
{
    auto delegate = adoptNS([[AsyncPolicyDelegateForInsetTest alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, viewHeight)]);
    [webView scrollView].contentInset = UIEdgeInsetsMake(400, 0, 0, 0);
    [webView setNavigationDelegate:delegate.get()];
    delegate->_navigationComplete = false;
    NSURL *testResourceURL = [[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:@"TestWebKitAPI.resources"];
    [webView loadHTMLString:veryTallDocumentMarkup baseURL:testResourceURL];
    Util::run(&delegate->_navigationComplete);

    __block bool presentationUpdateHappened = false;
    [webView _doAfterNextPresentationUpdate:^{
        presentationUpdateHappened = true;
    }];
    TestWebKitAPI::Util::run(&presentationUpdateHappened);

    CGPoint initialContentOffset = [webView scrollView].contentOffset;
    __block CGPoint contentOffsetAfterCrash = CGPointZero;
    __block bool done = false;
    [delegate setWebContentProcessDidTerminate:^(WKWebView *webView) {
        contentOffsetAfterCrash = webView.scrollView.contentOffset;
        done = true;
    }];

    [webView _killWebContentProcessAndResetState];
    Util::run(&done);

    EXPECT_EQ(initialContentOffset.x, contentOffsetAfterCrash.x);
    EXPECT_EQ(initialContentOffset.y, contentOffsetAfterCrash.y);
    EXPECT_EQ(0, initialContentOffset.x);
    EXPECT_EQ(-400, initialContentOffset.y);
}

} // namespace TestWebKitAPI

#endif // PLATFORM(IOS_FAMILY)
