/*
 * 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 "TestCocoa.h"
#import "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import <WebKit/WKPreferencesRefPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/WebKit.h>
#import <WebKit/_WKTextInputContext.h>
#import <wtf/RetainPtr.h>

@implementation WKWebView (SynchronousTextInputContext)

- (NSArray<_WKTextInputContext *> *)synchronouslyRequestTextInputContextsInRect:(CGRect)rect
{
    __block bool finished = false;
    __block RetainPtr<NSArray<_WKTextInputContext *>> result;
    [self _requestTextInputContextsInRect:rect completionHandler:^(NSArray<_WKTextInputContext *> *contexts) {
        result = contexts;
        finished = true;
    }];
    TestWebKitAPI::Util::run(&finished);
    return result.autorelease();
}

- (BOOL)synchronouslyFocusTextInputContext:(_WKTextInputContext *)context
{
    __block bool finished = false;
    __block bool success = false;
    [self _focusTextInputContext:context completionHandler:^(BOOL innerSuccess) {
        success = innerSuccess;
        finished = true;
    }];
    TestWebKitAPI::Util::run(&finished);
    return success;
}

@end

static NSString *applyStyle(NSString *HTMLString)
{
    return [@"<style>body { margin: 0; } iframe { border: none; }</style><meta name='viewport' content='initial-scale=1'>" stringByAppendingString:HTMLString];
}

static NSString *applyIframe(NSString *HTMLString)
{
    return applyStyle([NSString stringWithFormat:@"<iframe src=\"data:text/html,%@\" style='position: absolute; top: 200px;'>", [applyStyle(HTMLString) stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]]);
}

TEST(RequestTextInputContext, Simple)
{
    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    NSArray<_WKTextInputContext *> *contexts;

    // Basic inputs.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 50, 50), contexts[0].boundingRect);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<textarea style='width: 100px; height: 100px;'></textarea>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 100, 100), contexts[0].boundingRect);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<div contenteditable style='width: 100px; height: 100px;'></div>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 100, 100), contexts[0].boundingRect);

    // Basic inputs inside subframe.

    [webView synchronouslyLoadHTMLString:applyIframe(@"<input type='text' style='width: 50px; height: 50px;'>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 200, 50, 50), contexts[0].boundingRect);

    [webView synchronouslyLoadHTMLString:applyIframe(@"<textarea style='width: 100px; height: 100px;'></textarea>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 200, 100, 100), contexts[0].boundingRect);

    [webView synchronouslyLoadHTMLString:applyIframe(@"<div contenteditable style='width: 100px; height: 100px;'></div>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 200, 100, 100), contexts[0].boundingRect);

    // Read only inputs; should not be included.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;' readonly>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(0UL, contexts.count);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<textarea style='width: 100px; height: 100px;' readonly>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(0UL, contexts.count);

    // Inputs outside the requested rect; should not be included.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(100, 100, 100, 100)];
    EXPECT_EQ(0UL, contexts.count);

    // Inputs scrolled outside the requested rect; should not be included.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'><br><div style='width: 100px; height: 10000px;'></div>")];
    [webView stringByEvaluatingJavaScript:@"window.scrollTo(0, 5000)"];
    [webView waitForNextPresentationUpdate];
    EXPECT_EQ(5000, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(0UL, contexts.count);

    // Inputs scrolled into the requested rect.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px; position: absolute; top: 5000px;'><br><div style='width: 100px; height: 10000px;'></div>")];
    [webView stringByEvaluatingJavaScript:@"window.scrollTo(0, 5000)"];
    [webView waitForNextPresentationUpdate];
    EXPECT_EQ(5000, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 50, 50), contexts[0].boundingRect);

    // Multiple inputs.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'><br/><input type='text' style='width: 50px; height: 50px;'><br/><input type='text' style='width: 50px; height: 50px;'>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(3UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 100, 50, 50), contexts[0].boundingRect);
    EXPECT_EQ(CGRectMake(0, 50, 50, 50), contexts[1].boundingRect);
    EXPECT_EQ(CGRectMake(0, 0, 50, 50), contexts[2].boundingRect);

    // Nested <input>-inside-contenteditable.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<div contenteditable style='width: 100px; height: 100px;'><input type='text' style='width: 50px; height: 50px;'></div>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(2UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 50, 50), contexts[0].boundingRect);
    EXPECT_EQ(CGRectMake(0, 0, 100, 100), contexts[1].boundingRect);
}

TEST(RequestTextInputContext, DISABLED_FocusTextInputContext)
{
    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    WKPreferencesSetThreadedScrollingEnabled((WKPreferencesRef)[configuration preferences], false);
    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    NSArray<_WKTextInputContext *> *contexts;

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input id='test' type='text' style='width: 50px; height: 50px;'>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> originalInput = contexts[0];
    EXPECT_TRUE([webView synchronouslyFocusTextInputContext:originalInput.get()]);
    EXPECT_WK_STREQ("test", [webView objectByEvaluatingJavaScript:@"document.activeElement.id"]);

    // The _WKTextInputContext should still work even after another request.
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_TRUE([contexts[0] isEqual:originalInput.get()]);
    EXPECT_TRUE([webView synchronouslyFocusTextInputContext:originalInput.get()]);

    // Replace the <input> with a <textarea> with script; the <input> should no longer be focusable.
    [webView objectByEvaluatingJavaScript:@"document.body.innerHTML = '<textarea id=\"area\">';"];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> textArea = contexts[0];
    EXPECT_FALSE([textArea isEqual:originalInput.get()]);
    EXPECT_FALSE([webView synchronouslyFocusTextInputContext:originalInput.get()]);
    EXPECT_TRUE([webView synchronouslyFocusTextInputContext:textArea.get()]);
    EXPECT_WK_STREQ("area", [webView objectByEvaluatingJavaScript:@"document.activeElement.id"]);

    // Destroy the <textarea> by navigating away; we can no longer focus it.
    [webView synchronouslyLoadHTMLString:@""];
    EXPECT_FALSE([webView synchronouslyFocusTextInputContext:textArea.get()]);
}
