/*
 * Copyright (C) 2017 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 <WebKit/WKFoundation.h>

#if !PLATFORM(IOS_FAMILY_SIMULATOR)

#import "AdditionalReadAccessAllowedURLsProtocol.h"
#import "DeprecatedGlobalValues.h"
#import "PlatformUtilities.h"
#import "Utilities.h"
#import "WKWebViewConfigurationExtras.h"
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/_WKProcessPoolConfiguration.h>
#import <WebKit/_WKRemoteObjectInterface.h>
#import <WebKit/_WKRemoteObjectRegistry.h>
#import <wtf/RetainPtr.h>

TEST(WebKit, AdditionalReadAccessAllowedURLs)
{
    RetainPtr<WKWebViewConfiguration> configuration = retainPtr([WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"AdditionalReadAccessAllowedURLsPlugIn"]);

    _WKProcessPoolConfiguration *processPoolConfiguration = [configuration processPool]._configuration;

    bool exceptionRaised = false;
    @try {
        processPoolConfiguration.additionalReadAccessAllowedURLs = @[ [NSURL URLWithString:@"about:blank"] ];
    } @catch (NSException *exception) {
        EXPECT_WK_STREQ(NSInvalidArgumentException, exception.name);
        exceptionRaised = true;
    }
    EXPECT_TRUE(exceptionRaised);

    NSURL *fileURLWithNonLatin1Path = [NSURL fileURLWithPath:@"/这是中文"];
    processPoolConfiguration.additionalReadAccessAllowedURLs = @[ fileURLWithNonLatin1Path ];
    EXPECT_TRUE([processPoolConfiguration.additionalReadAccessAllowedURLs.firstObject isEqual:fileURLWithNonLatin1Path]);

    char temporaryDirectory[PATH_MAX];
    confstr(_CS_DARWIN_USER_TEMP_DIR, temporaryDirectory, sizeof(temporaryDirectory));

    char readableDirectory[PATH_MAX];
    strlcpy(readableDirectory, [[[NSFileManager defaultManager] stringWithFileSystemRepresentation:temporaryDirectory length:strlen(temporaryDirectory)] stringByAppendingPathComponent:@"WebKitTestRunner.AdditionalReadAccessAllowedURLs-XXXXXX"].fileSystemRepresentation, sizeof(temporaryDirectory));
    mkdtemp(readableDirectory);
    NSURL *readableDirectoryURL = [NSURL fileURLWithFileSystemRepresentation:readableDirectory isDirectory:YES relativeToURL:nil];

    char unreadableDirectory[PATH_MAX];
    strlcpy(unreadableDirectory, [[[NSFileManager defaultManager] stringWithFileSystemRepresentation:temporaryDirectory length:strlen(temporaryDirectory)] stringByAppendingPathComponent:@"WebKitTestRunner.AdditionalReadAccessAllowedURLs-XXXXXX"].fileSystemRepresentation, sizeof(temporaryDirectory));
    mkdtemp(unreadableDirectory);
    NSURL *unreadableDirectoryURL = [NSURL fileURLWithFileSystemRepresentation:unreadableDirectory isDirectory:YES relativeToURL:nil];

    processPoolConfiguration.additionalReadAccessAllowedURLs = @[ readableDirectoryURL ];

    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration]);
    [processPool _setObject:@"AdditionalReadAccessAllowedURLsPlugIn" forBundleParameter:TestWebKitAPI::Util::TestPlugInClassNameParameter];
    [configuration setProcessPool:processPool.get()];

    RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    id<AdditionalReadAccessAllowedURLsProtocol> proxy = [[webView _remoteObjectRegistry] remoteObjectProxyWithInterface:[_WKRemoteObjectInterface remoteObjectInterfaceWithProtocol:@protocol(AdditionalReadAccessAllowedURLsProtocol)]];

    NSURL *readableFileURL = [readableDirectoryURL URLByAppendingPathComponent:@"file"];
    NSURL *unreadableFileURL = [unreadableDirectoryURL URLByAppendingPathComponent:@"file"];

    [@"hello" writeToURL:readableFileURL atomically:YES encoding:NSUTF8StringEncoding error:nullptr];
    [@"secret" writeToURL:unreadableFileURL atomically:YES encoding:NSUTF8StringEncoding error:nullptr];

    [proxy readStringFromURL:readableFileURL completionHandler:^(NSString *string, NSError *error) {
        done = true;
        EXPECT_WK_STREQ(@"hello", string);
        EXPECT_EQ(nullptr, error);
    }];
    TestWebKitAPI::Util::run(&done);
    done = false;

    [proxy readStringFromURL:unreadableFileURL completionHandler:^(NSString *string, NSError *error) {
        done = true;
        EXPECT_EQ(nullptr, string);
        EXPECT_WK_STREQ(NSCocoaErrorDomain, error.domain);
        EXPECT_EQ(NSFileReadNoPermissionError, error.code);
    }];
    TestWebKitAPI::Util::run(&done);
}

#endif
