/*
 * Copyright (C) 2021 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 "Test.h"

#import "PlatformUtilities.h"
#import "TestProtocol.h"
#import "TestWKWebView.h"
#import "WKWebViewConfigurationExtras.h"
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WKWebpagePreferencesPrivate.h>
#import <WebKit/_WKModalContainerInfo.h>
#import <objc/runtime.h>
#import <wtf/FastMalloc.h>
#import <wtf/SetForScope.h>

@interface NSBundle (TestSupport)
- (NSURL *)swizzled_URLForResource:(NSString *)name withExtension:(NSString *)extension;
@end

@implementation NSBundle (TestSupport)

- (NSURL *)swizzled_URLForResource:(NSString *)name withExtension:(NSString *)extension
{
    if ([name isEqualToString:@"ModalContainerControls"] && [extension isEqualToString:@"mlmodelc"]) {
        // Override the default CoreML model with a smaller dataset that's limited to testing purposes.
        return [NSBundle.mainBundle URLForResource:@"TestModalContainerControls" withExtension:@"mlmodelc" subdirectory:@"TestWebKitAPI.resources"];
    }
    // Call through to the original method implementation if we're not specifically requesting ModalContainerControls.mlmodelc.
    return [self swizzled_URLForResource:name withExtension:extension];
}

@end

namespace TestWebKitAPI {

class ClassifierModelSwizzler {
    WTF_MAKE_FAST_ALLOCATED;
public:
    ClassifierModelSwizzler()
        : m_originalMethod(class_getInstanceMethod(NSBundle.class, @selector(URLForResource:withExtension:)))
        , m_swizzledMethod(class_getInstanceMethod(NSBundle.class, @selector(swizzled_URLForResource:withExtension:)))
    {
        m_originalImplementation = method_getImplementation(m_originalMethod);
        m_swizzledImplementation = method_getImplementation(m_swizzledMethod);
        class_replaceMethod(NSBundle.class, @selector(swizzled_URLForResource:withExtension:), m_originalImplementation, method_getTypeEncoding(m_originalMethod));
        class_replaceMethod(NSBundle.class, @selector(URLForResource:withExtension:), m_swizzledImplementation, method_getTypeEncoding(m_swizzledMethod));
    }

    ~ClassifierModelSwizzler()
    {
        class_replaceMethod(NSBundle.class, @selector(swizzled_URLForResource:withExtension:), m_swizzledImplementation, method_getTypeEncoding(m_originalMethod));
        class_replaceMethod(NSBundle.class, @selector(URLForResource:withExtension:), m_originalImplementation, method_getTypeEncoding(m_swizzledMethod));
    }

private:
    Method m_originalMethod;
    Method m_swizzledMethod;
    IMP m_originalImplementation;
    IMP m_swizzledImplementation;
};

} // namespace TestWebKitAPI

@interface ModalContainerWebView : TestWKWebView <WKUIDelegatePrivate>
@property (nonatomic) _WKModalContainerDecision decision;
@property (nonatomic, readonly) _WKModalContainerInfo *lastModalContainerInfo;
@end

@implementation ModalContainerWebView {
    std::unique_ptr<TestWebKitAPI::ClassifierModelSwizzler> _classifierModelSwizzler;
    RetainPtr<TestNavigationDelegate> _navigationDelegate;
    RetainPtr<_WKModalContainerInfo> _lastModalContainerInfo;
    bool _doneWaitingForDecisionHandler;
}

- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
{
    if (!(self = [super initWithFrame:frame configuration:configuration]))
        return nil;

    static std::once_flag onceFlag;
    std::call_once(onceFlag, [] {
        [TestProtocol registerWithScheme:@"http"];
    });

    _decision = _WKModalContainerDecisionShow;
    _classifierModelSwizzler = makeUnique<TestWebKitAPI::ClassifierModelSwizzler>();
    _navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
    _doneWaitingForDecisionHandler = true;
    [self setNavigationDelegate:_navigationDelegate.get()];
    [self setUIDelegate:self];
    return self;
}

- (void)loadBundlePage:(NSString *)page andDecidePolicy:(_WKModalContainerDecision)decision
{
    SetForScope decisionScope { _decision, decision };
    _doneWaitingForDecisionHandler = false;

    [self loadBundlePage:page];

    TestWebKitAPI::Util::run(&_doneWaitingForDecisionHandler);
    [self waitForNextPresentationUpdate];
}

- (void)evaluate:(NSString *)script andDecidePolicy:(_WKModalContainerDecision)decision
{
    SetForScope decisionScope { _decision, decision };
    _doneWaitingForDecisionHandler = false;

    [self objectByEvaluatingJavaScript:script];

    TestWebKitAPI::Util::run(&_doneWaitingForDecisionHandler);
    [self waitForNextPresentationUpdate];
}

- (void)loadBundlePage:(NSString *)page
{
    NSURL *bundleURL = [NSBundle.mainBundle URLForResource:page withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
    NSURLRequest *fakeRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://webkit.org"]];
    [self loadSimulatedRequest:fakeRequest responseHTMLString:[NSString stringWithContentsOfURL:bundleURL]];

    auto preferences = adoptNS([[WKWebpagePreferences alloc] init]);
    [preferences _setModalContainerObservationPolicy:_WKWebsiteModalContainerObservationPolicyPrompt];
    [_navigationDelegate waitForDidFinishNavigationWithPreferences:preferences.get()];
}

- (void)loadHTML:(NSString *)html
{
    NSURLRequest *fakeRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://webkit.org"]];
    [self loadSimulatedRequest:fakeRequest responseHTMLString:html];

    auto preferences = adoptNS([[WKWebpagePreferences alloc] init]);
    [preferences _setModalContainerObservationPolicy:_WKWebsiteModalContainerObservationPolicyPrompt];
    [_navigationDelegate waitForDidFinishNavigationWithPreferences:preferences.get()];
}

- (void)waitForText:(NSString *)text
{
    TestWebKitAPI::Util::waitForConditionWithLogging([&]() -> bool {
        return [self.contentsAsString containsString:text];
    }, 3, @"Timed out waiting for '%@'", text);
}

- (void)_webView:(WKWebView *)webView decidePolicyForModalContainer:(_WKModalContainerInfo *)containerInfo decisionHandler:(void (^)(_WKModalContainerDecision))handler
{
    handler(_decision);
    _lastModalContainerInfo = containerInfo;
    _doneWaitingForDecisionHandler = true;
}

- (_WKModalContainerInfo *)lastModalContainerInfo
{
    return _lastModalContainerInfo.get();
}

@end

namespace TestWebKitAPI {

static RetainPtr<ModalContainerWebView> createModalContainerWebView()
{
    auto configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
    return adoptNS([[ModalContainerWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration]);
}

constexpr auto allControlTypes = _WKModalContainerControlTypeNeutral | _WKModalContainerControlTypePositive | _WKModalContainerControlTypeNegative;

TEST(ModalContainerObservation, HideAndAllowModalContainer)
{
    auto webView = createModalContainerWebView();
    [webView loadBundlePage:@"modal-container" andDecidePolicy:_WKModalContainerDecisionHideAndAllow];
    NSString *visibleText = [webView contentsAsString];
    EXPECT_TRUE([visibleText containsString:@"Clicked on \"Yes\""]);
    EXPECT_FALSE([visibleText containsString:@"Hello world"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, allControlTypes);
}

TEST(ModalContainerObservation, HideAndDisallowModalContainer)
{
    auto webView = createModalContainerWebView();
    [webView loadBundlePage:@"modal-container" andDecidePolicy:_WKModalContainerDecisionHideAndDisallow];
    NSString *visibleText = [webView contentsAsString];
    EXPECT_TRUE([visibleText containsString:@"Clicked on \"No\""]);
    EXPECT_FALSE([visibleText containsString:@"Hello world"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, allControlTypes);
}

TEST(ModalContainerObservation, HideAndIgnoreModalContainer)
{
    auto webView = createModalContainerWebView();
    [webView loadBundlePage:@"modal-container" andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];
    NSString *visibleText = [webView contentsAsString];
    EXPECT_FALSE([visibleText containsString:@"Clicked on"]);
    EXPECT_FALSE([visibleText containsString:@"Hello world"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, allControlTypes);
}

TEST(ModalContainerObservation, ShowModalContainer)
{
    auto webView = createModalContainerWebView();
    [webView loadBundlePage:@"modal-container" andDecidePolicy:_WKModalContainerDecisionShow];
    NSString *visibleText = [webView contentsAsString];
    EXPECT_FALSE([visibleText containsString:@"Clicked on"]);
    EXPECT_TRUE([visibleText containsString:@"Hello world"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, allControlTypes);
}

TEST(ModalContainerObservation, ClassifyMultiplySymbol)
{
    auto webView = createModalContainerWebView();
    auto runTest = [&] (NSString *symbol) {
        [webView loadBundlePage:@"modal-container-custom"];
        NSString *scriptToEvaluate = [NSString stringWithFormat:@"show(`<p>Hello world</p><button>%@</button>`)", symbol];
        [webView evaluate:scriptToEvaluate andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];

        EXPECT_FALSE([[webView contentsAsString] containsString:@"Hello world"]);
        EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypeNeutral);
    };
    runTest(@"✕");
    runTest(@"⨯");
}

TEST(ModalContainerObservation, DetectSearchTermInBoldTag)
{
    auto webView = createModalContainerWebView();
    [webView loadBundlePage:@"modal-container-custom"];
    [webView evaluate:@"show(`<b>Hello world</b><a href='#'>Yes</a><a href='#'>No</a>`)" andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];

    EXPECT_FALSE([[webView contentsAsString] containsString:@"Hello world"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypePositive | _WKModalContainerControlTypeNegative);
}

TEST(ModalContainerObservation, HideUserInteractionBlockingElementAndMakeDocumentScrollable)
{
    auto webView = createModalContainerWebView();
    [webView loadBundlePage:@"modal-container-with-overlay" andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];

    EXPECT_FALSE([[webView contentsAsString] containsString:@"Hello world"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypePositive);

    NSString *hitTestedText = [webView stringByEvaluatingJavaScript:@"document.elementFromPoint(50, 50).textContent"];
    EXPECT_TRUE([hitTestedText containsString:@"Lorem"]);
    EXPECT_WK_STREQ("auto", [webView stringByEvaluatingJavaScript:@"getComputedStyle(document.documentElement).overflowY"]);
    EXPECT_WK_STREQ("auto", [webView stringByEvaluatingJavaScript:@"getComputedStyle(document.body).overflowY"]);
}

TEST(ModalContainerObservation, IgnoreFixedDocumentElement)
{
    auto webView = createModalContainerWebView();
    [webView setDecision:_WKModalContainerDecisionHideAndIgnore];
    [webView loadHTML:@("<head>"
        "<script>internals.overrideModalContainerSearchTermForTesting('foo')</script>"
        "<style>html { position: fixed; width: 100%; height: 100%; top: 0; left: 0; }</style>"
        "</head><body><h1>foo bar</h1></body>")];

    EXPECT_TRUE([[webView contentsAsString] containsString:@"foo bar"]);
    EXPECT_NULL([webView lastModalContainerInfo]);
}

TEST(ModalContainerObservation, IgnoreNavigationElements)
{
    auto webView = createModalContainerWebView();
    [webView setDecision:_WKModalContainerDecisionHideAndIgnore];
    [webView loadBundlePage:@"modal-container-custom"];
    [webView objectByEvaluatingJavaScript:@"show(`<nav>hello world 1</nav><div role='navigation'>hello world 2</div>`)"];
    [webView waitForNextPresentationUpdate];

    EXPECT_TRUE([[webView contentsAsString] containsString:@"hello world 1"]);
    EXPECT_TRUE([[webView contentsAsString] containsString:@"hello world 2"]);
    EXPECT_NULL([webView lastModalContainerInfo]);
}

TEST(ModalContainerObservation, ShowModalContainerAfterFalsePositive)
{
    auto webView = createModalContainerWebView();
    [webView setDecision:_WKModalContainerDecisionHideAndIgnore];
    [webView loadBundlePage:@"modal-container-custom"];
    [webView objectByEvaluatingJavaScript:@"show(`<div>hello world</div><a href='https://apple.com'>Click here</a>`)"];
    [webView waitForNextPresentationUpdate];
    [webView waitForText:@"hello world"];
    EXPECT_NULL([webView lastModalContainerInfo]);
}

TEST(ModalContainerObservation, ModalContainerInSubframe)
{
    auto webView = createModalContainerWebView();
    [webView setDecision:_WKModalContainerDecisionHideAndIgnore];
    [webView loadBundlePage:@"modal-container-custom"];
    [webView evaluate:@"show(`<p>subframe test</p><iframe srcdoc='<h2>hello world</h2><button>YES</button>'></iframe>`)" andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];
    EXPECT_FALSE([[webView contentsAsString] containsString:@"subframe test"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypePositive);
}

TEST(ModalContainerObservation, DetectModalContainerAfterSettingText)
{
    auto webView = createModalContainerWebView();
    [webView loadBundlePage:@"modal-container-custom"];
    [webView objectByEvaluatingJavaScript:@"show(`<div id='content'></div>`)"];
    [webView waitForNextPresentationUpdate];
    [webView evaluate:@"document.getElementById('content').innerHTML = `hello world <a href='#'>no</a>`" andDecidePolicy:_WKModalContainerDecisionHideAndIgnore];
    EXPECT_FALSE([[webView contentsAsString] containsString:@"hello world"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypeNegative);
}

TEST(ModalContainerObservation, DetectControlsWithEventListenersOnModalContainer)
{
    auto webView = createModalContainerWebView();
    [webView loadBundlePage:@"modal-container-custom"];
    auto script = @"showWithEventListener(`<div>Hello world <span style='cursor: pointer;'>yes</span></div>`, 'click', () => window.testPassed = true)";
    [webView evaluate:script andDecidePolicy:_WKModalContainerDecisionHideAndAllow];
    [webView waitForNextPresentationUpdate];
    EXPECT_FALSE([[webView contentsAsString] containsString:@"Hello world"]);
    EXPECT_EQ([webView lastModalContainerInfo].availableTypes, _WKModalContainerControlTypePositive);
    EXPECT_TRUE([[webView objectByEvaluatingJavaScript:@"window.testPassed"] boolValue]);
}

} // namespace TestWebKitAPI
