/*
 * 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 "HTTPServer.h"
#import "PlatformUtilities.h"
#import "RemoteObjectRegistry.h"
#import "Test.h"
#import "TestAwakener.h"
#import "TestNavigationDelegate.h"
#import "WKWebViewConfigurationExtras.h"
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/_WKRemoteObjectInterface.h>
#import <WebKit/_WKRemoteObjectRegistry.h>
#import <wtf/BlockPtr.h>
#import <wtf/RefCounted.h>
#import <wtf/RetainPtr.h>
#import <wtf/WeakObjCPtr.h>

TEST(RemoteObjectRegistry, Basic)
{
    __block bool isDone = false;

    @autoreleasepool {
        NSString * const testPlugInClassName = @"RemoteObjectRegistryPlugIn";
        auto configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:testPlugInClassName]);
        configuration.get()._groupIdentifier = @"testGroupIdentifier";
        auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);

        isDone = false;

        _WKRemoteObjectInterface *interface = remoteObjectInterface();
        id <RemoteObjectProtocol> object = [[webView _remoteObjectRegistry] remoteObjectProxyWithInterface:interface];

        [object sayHello:@"Hello, World!"];

        [webView evaluateJavaScript:@"helloString" completionHandler:^(id result, NSError *error) {
            EXPECT_TRUE([result isKindOfClass:[NSString class]]);
            EXPECT_WK_STREQ(result, @"Hello, World!");
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;
        [object sayHello:@"Hello Again!" completionHandler:^(NSString *result) {
            EXPECT_TRUE([result isKindOfClass:[NSString class]]);
            EXPECT_WK_STREQ(result, @"Your string was 'Hello Again!'");
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;
        [object selectionAndClickInformationForClickAtPoint:[NSValue valueWithPoint:NSMakePoint(12, 34)] completionHandler:^(NSDictionary *result) {
            EXPECT_TRUE([result isEqual:@{ @"URL": [NSURL URLWithString:@"http://www.webkit.org/"] }]);
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;
        [object takeRange:NSMakeRange(345, 123) completionHandler:^(NSUInteger location, NSUInteger length) {
            EXPECT_EQ(345U, location);
            EXPECT_EQ(123U, length);
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;
        auto initialAwakener = adoptNS([[TestAwakener alloc] initWithValue:42]);
        [object sendAwakener:initialAwakener.get() completionHandler:^(TestAwakener *awakener) {
            EXPECT_EQ(awakener.value, 42);
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;
        [object takeSize:CGSizeMake(123.45, 678.91) completionHandler:^(CGFloat width, CGFloat height) {
            EXPECT_EQ(123.45, width);
            EXPECT_EQ(678.91, height);
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;

        [object takeUnsignedLongLong:std::numeric_limits<unsigned long long>::max() completionHandler:^(unsigned long long value) {
            EXPECT_EQ(std::numeric_limits<unsigned long long>::max(), value);
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;

        [object takeLongLong:std::numeric_limits<long long>::max() completionHandler:^(long long value) {
            EXPECT_EQ(std::numeric_limits<long long>::max(), value);
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;

        [object takeUnsignedLong:std::numeric_limits<unsigned long>::max() completionHandler:^(unsigned long value) {
            EXPECT_EQ(std::numeric_limits<unsigned long>::max(), value);
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;

        [object takeLong:std::numeric_limits<long>::max() completionHandler:^(long value) {
            EXPECT_EQ(std::numeric_limits<long>::max(), value);
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;

        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://webkit.org/"]];
        auto response = adoptNS([[NSHTTPURLResponse alloc] initWithURL:[NSURL URLWithString:@"https://webkit.org/"] statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:@{ @"testFieldName" : @"testFieldValue" }]);
        NSError *error = [NSError errorWithDomain:@"testDomain" code:123 userInfo:@{@"a":@"b"}];
        auto protectionSpace = adoptNS([[NSURLProtectionSpace alloc] initWithHost:@"testHost" port:80 protocol:@"testProtocol" realm:@"testRealm" authenticationMethod:NSURLAuthenticationMethodHTTPDigest]);
        NSURLCredential *credential = [NSURLCredential credentialWithUser:@"testUser" password:@"testPassword" persistence:NSURLCredentialPersistenceForSession];
        id<NSURLAuthenticationChallengeSender> sender = nil;
        auto challenge = adoptNS([[NSURLAuthenticationChallenge alloc] initWithProtectionSpace:protectionSpace.get() proposedCredential:credential previousFailureCount:42 failureResponse:response.get() error:error sender:sender]);
        [object sendRequest:request response:response.get() challenge:challenge.get() error:error completionHandler:^(NSURLRequest *deserializedRequest, NSURLResponse *deserializedResponse, NSURLAuthenticationChallenge *deserializedChallenge, NSError *deserializedError) {
            EXPECT_WK_STREQ(deserializedRequest.URL.absoluteString, "https://webkit.org/");
            EXPECT_WK_STREQ([(NSHTTPURLResponse *)deserializedResponse allHeaderFields][@"testFieldName"], "testFieldValue");
            EXPECT_WK_STREQ(deserializedChallenge.protectionSpace.realm, "testRealm");
            EXPECT_WK_STREQ(deserializedError.domain, "testDomain");
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;
        
        [object getGroupIdentifier:^(NSString *identifier) {
            EXPECT_WK_STREQ(identifier, "testGroupIdentifier");
            isDone = true;
        }];
        TestWebKitAPI::Util::run(&isDone);

        isDone = false;

        bool exceptionThrown = false;
        NSMutableDictionary *child = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"foo", @"name", [NSNumber numberWithInt:1], @"value", nil];
        NSMutableDictionary *dictionaryWithCycle = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"root", @"name", child, @"child", nil];
        [child setValue:dictionaryWithCycle forKey:@"parent"]; // Creates a cycle.
        @try {
            [object takeDictionary:dictionaryWithCycle completionHandler:^(NSDictionary* value) {
                EXPECT_TRUE(!value.count);
                isDone = true;
            }];
            TestWebKitAPI::Util::run(&isDone);
            isDone = false;
        } @catch (NSException *e) {
            exceptionThrown = true;
        }
        EXPECT_FALSE(exceptionThrown);

        class DoneWhenDestroyed : public RefCounted<DoneWhenDestroyed> {
        public:
            DoneWhenDestroyed(bool& isDone)
                : isDone(isDone) { }
            ~DoneWhenDestroyed() { isDone = true; }
        private:
            bool& isDone;
        };

        {
            RefPtr<DoneWhenDestroyed> doneWhenDestroyed = adoptRef(*new DoneWhenDestroyed(isDone));
            [object doNotCallCompletionHandler:[doneWhenDestroyed]() {
            }];
        }

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

@interface LocalObject : NSObject<LocalObjectProtocol> {
@public
    BlockPtr<void()> completionHandlerFromWebProcess;
    bool hasCompletionHandler;
}
@end

@implementation LocalObject

- (void)doSomethingWithCompletionHandler:(void (^)(void))completionHandler
{
    completionHandlerFromWebProcess = completionHandler;
    hasCompletionHandler = true;
}

@end

TEST(RemoteObjectRegistry, CallReplyBlockAfterOriginatingWebViewDeallocates)
{
    auto localObject = adoptNS([[LocalObject alloc] init]);
    WeakObjCPtr<WKWebView> weakWebViewPtr;

    @autoreleasepool {
        NSString * const testPlugInClassName = @"RemoteObjectRegistryPlugIn";
        auto configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:testPlugInClassName]);
        auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
        weakWebViewPtr = webView.get();

        _WKRemoteObjectInterface *interface = remoteObjectInterface();
        id <RemoteObjectProtocol> object = [[webView _remoteObjectRegistry] remoteObjectProxyWithInterface:interface];

        [[webView _remoteObjectRegistry] registerExportedObject:localObject.get() interface:localObjectInterface()];

        [object callUIProcessMethodWithReplyBlock];

        TestWebKitAPI::Util::run(&localObject->hasCompletionHandler);
    }

    while (true) {
        @autoreleasepool {
            if (!weakWebViewPtr.get())
                break;

            TestWebKitAPI::Util::spinRunLoop();
        }
    }

    localObject->completionHandlerFromWebProcess();
}

TEST(RemoteObjectRegistry, SerializeErrorWithCertificates)
{
    TestWebKitAPI::HTTPServer server({ }, TestWebKitAPI::HTTPServer::Protocol::Https);
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:[WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"RemoteObjectRegistryPlugIn"]]);
    auto delegate = adoptNS([TestNavigationDelegate new]);
    webView.get().navigationDelegate = delegate.get();
    [webView loadRequest:server.request()];
    NSError *error = [delegate waitForDidFailProvisionalNavigation];
    NSString *key = @"NSErrorPeerCertificateChainKey";
    EXPECT_WK_STREQ(error.domain, "NSURLErrorDomain");
    EXPECT_TRUE(error.userInfo[key]);
    
    _WKRemoteObjectInterface *interface = [_WKRemoteObjectInterface remoteObjectInterfaceWithProtocol:@protocol(RemoteObjectProtocol)];
    id <RemoteObjectProtocol> object = [[webView _remoteObjectRegistry] remoteObjectProxyWithInterface:interface];
    __block bool roundTripComplete = false;
    [object sendError:error completionHandler:^(NSError *deserializedError) {
        EXPECT_WK_STREQ(deserializedError.domain, "NSURLErrorDomain");
        NSArray *chain = deserializedError.userInfo[key];
        EXPECT_TRUE(chain);
        EXPECT_EQ(CFGetTypeID(chain[0]), SecCertificateGetTypeID());
        roundTripComplete = true;
    }];
    TestWebKitAPI::Util::run(&roundTripComplete);
}
