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

#import "config.h"

#import "TestWKWebView.h"
#import "Utilities.h"
#import <Foundation/NSProgress.h>
#import <WebKit/WKBrowsingContextController.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebViewConfiguration.h>
#import <WebKit/_WKDownload.h>
#import <WebKit/_WKDownloadDelegate.h>
#import <pal/spi/cocoa/NSProgressSPI.h>
#import <wtf/BlockPtr.h>
#import <wtf/FileSystem.h>
#import <wtf/RetainPtr.h>
#import <wtf/WeakObjCPtr.h>

@class DownloadProgressTestProtocol;

enum class DownloadStartType {
    ConvertLoadToDownload,
    StartFromNavigationAction,
    StartInProcessPool,
};

@interface DownloadProgressTestRunner : NSObject <WKNavigationDelegate, _WKDownloadDelegate>

@property (nonatomic, readonly) _WKDownload *download;
@property (nonatomic, readonly) NSProgress *progress;

- (void)startLoadingWithProtocol:(DownloadProgressTestProtocol *)protocol;

@end

@interface DownloadProgressTestProtocol : NSURLProtocol
@end

@implementation DownloadProgressTestProtocol

static DownloadProgressTestRunner *currentTestRunner;

+ (void)registerProtocolForTestRunner:(DownloadProgressTestRunner *)testRunner
{
    currentTestRunner = testRunner;
    [NSURLProtocol registerClass:self];
    [WKBrowsingContextController registerSchemeForCustomProtocol:@"http"];
}

+ (void)unregisterProtocol
{
    currentTestRunner = nullptr;
    [WKBrowsingContextController unregisterSchemeForCustomProtocol:@"http"];
    [NSURLProtocol unregisterClass:self];
}

// MARK: NSURLProtocol Methods

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    return [request.URL.scheme caseInsensitiveCompare:@"http"] == NSOrderedSame;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
    return request;
}

+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b
{
    return NO;
}

- (void)startLoading
{
    [currentTestRunner startLoadingWithProtocol:self];
}

- (void)stopLoading
{
}

@end

static void* progressObservingContext = &progressObservingContext;

@implementation DownloadProgressTestRunner {
    RetainPtr<NSURL> m_progressURL;
    RetainPtr<TestWKWebView> m_webView;
    RetainPtr<id> m_progressSubscriber;
    RetainPtr<NSProgress> m_progress;
    RetainPtr<_WKDownload> m_download;
    RetainPtr<DownloadProgressTestProtocol> m_protocol;
    BlockPtr<void(void)> m_unpublishingBlock;
    DownloadStartType m_startType;
    NSInteger m_expectedLength;
    bool m_hasProgress;
    bool m_lostProgress;
    bool m_downloadStarted;
    bool m_downloadDidCreateDestination;
    bool m_downloadFinished;
    bool m_downloadCanceled;
    bool m_downloadFailed;
    bool m_hasUpdatedCompletedUnitCount;
}

- (instancetype)init
{
    self = [super init];

    [DownloadProgressTestProtocol registerProtocolForTestRunner:self];

    NSString *fileName = [NSString stringWithFormat:@"download-progress-%@", [NSUUID UUID].UUIDString];
    m_progressURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName] isDirectory:NO];

    currentTestRunner = self;

    m_unpublishingBlock = makeBlockPtr([self] {
        [self _didLoseProgress];
    }).get();

    return self;
}

- (_WKDownload *)download
{
    return m_download.get();
}

- (NSProgress *)progress
{
    return m_progress.get();
}

- (void)startLoadingWithProtocol:(DownloadProgressTestProtocol *)protocol
{
    m_protocol = protocol;

    auto response = adoptNS([[NSURLResponse alloc] initWithURL:protocol.request.URL MIMEType:@"application/x-test-file" expectedContentLength:m_expectedLength textEncodingName:nullptr]);
    [m_protocol.get().client URLProtocol:m_protocol.get() didReceiveResponse:response.get() cacheStoragePolicy:NSURLCacheStorageNotAllowed];
}

- (void)tearDown
{
    if (m_webView) {
        m_webView.get().configuration.processPool._downloadDelegate = nullptr;
        [m_webView.get() removeFromSuperview];
        m_webView = nullptr;
    }

    if (m_progressSubscriber) {
#if USE(NSPROGRESS_PUBLISHING_SPI)
        [NSProgress _removeSubscriber:m_progressSubscriber.get()];
#else
        [NSProgress removeSubscriber:m_progressSubscriber.get()];
#endif
        m_progressSubscriber = nullptr;
    }

    m_progress = nullptr;
    m_download = nullptr;
    m_protocol = nullptr;
    m_unpublishingBlock = nullptr;

    [DownloadProgressTestProtocol unregisterProtocol];
}

- (void)_didGetProgress:(NSProgress *)progress
{
    ASSERT(!m_progress);
    m_progress = progress;
    [progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:progressObservingContext];
    m_hasProgress = true;
}

- (void)_didLoseProgress
{
    ASSERT(m_progress);
    [m_progress.get() removeObserver:self forKeyPath:@"completedUnitCount"];
    m_progress = nullptr;
    m_lostProgress = true;
}

- (void)subscribeAndWaitForProgress
{
    if (!m_progressSubscriber) {
        auto publishingHandler = makeBlockPtr([weakSelf = WeakObjCPtr<DownloadProgressTestRunner> { self }](NSProgress *progress) {
            if (auto strongSelf = weakSelf.get()) {
                [strongSelf.get() _didGetProgress:progress];
                return strongSelf->m_unpublishingBlock.get();
            }
            return static_cast<NSProgressUnpublishingHandler>(nil);
        });

#if USE(NSPROGRESS_PUBLISHING_SPI)
        m_progressSubscriber = [NSProgress _addSubscriberForFileURL:m_progressURL.get() withPublishingHandler:publishingHandler.get()];
#else
        m_progressSubscriber = [NSProgress addSubscriberForFileURL:m_progressURL.get() withPublishingHandler:publishingHandler.get()];
#endif
    }
    TestWebKitAPI::Util::run(&m_hasProgress);
}

- (void)waitToLoseProgress
{
    TestWebKitAPI::Util::run(&m_lostProgress);
}

- (void)startDownload:(DownloadStartType)startType expectedLength:(NSInteger)expectedLength
{
    m_startType = startType;
    m_expectedLength = expectedLength;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    m_webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
    m_webView.get().navigationDelegate = self;
    m_webView.get().configuration.processPool._downloadDelegate = self;

    auto request = adoptNS([[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://file"]]);

    switch (startType) {
    case DownloadStartType::ConvertLoadToDownload:
    case DownloadStartType::StartFromNavigationAction:
        [m_webView loadRequest:request.get()];
        break;
    case DownloadStartType::StartInProcessPool:
        [m_webView.get().configuration.processPool _downloadURLRequest:request.get() websiteDataStore:[WKWebsiteDataStore defaultDataStore] originatingWebView:nullptr];
        break;
    }

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

- (void)publishProgress
{
    ASSERT(m_download);

    [m_download.get() publishProgressAtURL:m_progressURL.get()];
}

- (void)receiveData:(NSInteger)length
{
    auto data = adoptNS([[NSMutableData alloc] init]);
    while (length-- > 0) {
        const char byte = 'A';
        [data.get() appendBytes:static_cast<const void*>(&byte) length:1];
    }

    [m_protocol.get().client URLProtocol:m_protocol.get() didLoadData:data.get()];
}

- (void)finishDownloadTask
{
    [m_protocol.get().client URLProtocolDidFinishLoading:m_protocol.get()];
}

- (void)failDownloadTask
{
    [m_protocol.get().client URLProtocol:m_protocol.get() didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorNetworkConnectionLost userInfo:nullptr]];
}

- (void)waitForDownloadDidCreateDestination
{
    TestWebKitAPI::Util::run(&m_downloadDidCreateDestination);
}

- (void)waitForDownloadFinished
{
    TestWebKitAPI::Util::run(&m_downloadFinished);
}

- (void)waitForDownloadCanceled
{
    TestWebKitAPI::Util::run(&m_downloadCanceled);
}

- (void)waitForDownloadFailed
{
    TestWebKitAPI::Util::run(&m_downloadFailed);
}

- (int64_t)waitForUpdatedCompletedUnitCount
{
    TestWebKitAPI::Util::run(&m_hasUpdatedCompletedUnitCount);
    m_hasUpdatedCompletedUnitCount = false;

    return m_progress.get().completedUnitCount;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey, id> *)change context:(void *)context
{
    if (context == progressObservingContext) {
        EXPECT_EQ(object, m_progress.get());
        EXPECT_STREQ(keyPath.UTF8String, "completedUnitCount");
        m_hasUpdatedCompletedUnitCount = true;
    } else
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}

// MARK: <WKNavigationDelegate> Methods

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    if (m_startType == DownloadStartType::ConvertLoadToDownload)
        decisionHandler(_WKNavigationResponsePolicyBecomeDownload);
    else
        decisionHandler(WKNavigationResponsePolicyAllow);
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    if (m_startType == DownloadStartType::StartFromNavigationAction)
        decisionHandler(_WKNavigationActionPolicyDownload);
    else
        decisionHandler(WKNavigationActionPolicyAllow);
}

// MARK: <_WKDownloadDelegate> Methods

- (void)_downloadDidStart:(_WKDownload *)download
{
    ASSERT(!m_downloadStarted);
    ASSERT(!m_download);

    m_download = download;
    m_downloadStarted = true;
}

- (void)_download:(_WKDownload *)download didCreateDestination:(NSString *)destination
{
    EXPECT_EQ(download, m_download.get());
    m_downloadDidCreateDestination = true;
}

- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_EQ(download, m_download.get());
    m_downloadFinished = true;
}

- (void)_downloadDidCancel:(_WKDownload *)download
{
    EXPECT_EQ(download, m_download.get());
    m_downloadCanceled = true;
}

- (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
{
    EXPECT_EQ(download, m_download.get());
    m_downloadFailed = true;
}

- (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL allowOverwrite, NSString *destination))completionHandler
{
    EXPECT_EQ(download, m_download.get());

    FileSystem::PlatformFileHandle fileHandle;
    RetainPtr<NSString> path = (NSString *)FileSystem::openTemporaryFile("TestWebKitAPI", fileHandle);
    EXPECT_TRUE(fileHandle != FileSystem::invalidPlatformFileHandle);
    FileSystem::closeFile(fileHandle);

    completionHandler(YES, path.get());
}

@end

// End-to-end test of subscribing to progress on a successful download. The client
// should be able to receive an NSProgress that is updated as the download makes
// progress, and the NSProgress should be unpublished when the download finishes.
TEST(DownloadProgress, BasicSubscriptionAndProgressUpdates)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::ConvertLoadToDownload expectedLength:100];
    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];

    [testRunner.get() receiveData:50];
    EXPECT_EQ([testRunner.get() waitForUpdatedCompletedUnitCount], 50);
    EXPECT_EQ(testRunner.get().progress.fractionCompleted, .5);

    [testRunner.get() receiveData:50];
    EXPECT_EQ([testRunner.get() waitForUpdatedCompletedUnitCount], 100);
    EXPECT_EQ(testRunner.get().progress.fractionCompleted, 1);

    [testRunner.get() finishDownloadTask];
    [testRunner.get() waitForDownloadFinished];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}

// Similar test as before, but initiating the download before receiving its response.
TEST(DownloadProgress, StartDownloadFromNavigationAction)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::StartFromNavigationAction expectedLength:100];
    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];
    [testRunner.get() receiveData:100];
    [testRunner.get() finishDownloadTask];
    [testRunner.get() waitForDownloadFinished];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}

TEST(DownloadProgress, StartDownloadInProcessPool)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::StartInProcessPool expectedLength:100];
    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];
    [testRunner.get() receiveData:100];
    [testRunner.get() finishDownloadTask];
    [testRunner.get() waitForDownloadFinished];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}

// If the download is canceled, the progress should be unpublished.
TEST(DownloadProgress, LoseProgressWhenDownloadIsCanceled)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::ConvertLoadToDownload expectedLength:100];
    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];
    [testRunner.get() receiveData:50];
    [testRunner.get().download cancel];
    [testRunner.get() waitForDownloadCanceled];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}

// If the download fails, the progress should be unpublished.
TEST(DownloadProgress, LoseProgressWhenDownloadFails)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::ConvertLoadToDownload expectedLength:100];
    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];
    [testRunner.get() receiveData:50];
    [testRunner.get() failDownloadTask];
    [testRunner.get() waitForDownloadFailed];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}

// Canceling the progress should cancel the download.
TEST(DownloadProgress, CancelDownloadWhenProgressIsCanceled)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::ConvertLoadToDownload expectedLength:100];
    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];
    [testRunner.get() receiveData:50];
    [testRunner.get().progress cancel];
    [testRunner.get() waitForDownloadCanceled];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}

// Publishing progress on a download after it has finished should be a safe no-op.
TEST(DownloadProgress, PublishProgressAfterDownloadFinished)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::ConvertLoadToDownload expectedLength:100];
    [testRunner.get() receiveData:100];
    [testRunner.get() finishDownloadTask];
    [testRunner.get() waitForDownloadFinished];
    [testRunner.get() publishProgress];

    [testRunner.get() tearDown];
}

// Test the behavior of a download of unknown length.
TEST(DownloadProgress, IndeterminateDownloadSize)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::ConvertLoadToDownload expectedLength:NSURLResponseUnknownLength];
    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];
    EXPECT_EQ(testRunner.get().progress.totalUnitCount, -1);

    [testRunner.get() receiveData:50];
    EXPECT_EQ([testRunner.get() waitForUpdatedCompletedUnitCount], 50);
    EXPECT_EQ(testRunner.get().progress.fractionCompleted, 0);
    EXPECT_EQ(testRunner.get().progress.totalUnitCount, -1);

    [testRunner.get() finishDownloadTask];
    [testRunner.get() waitForDownloadFinished];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}

// Test the behavior when a download continues returning data beyond its expected length.
TEST(DownloadProgress, ExtraData)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::ConvertLoadToDownload expectedLength:100];
    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];

    [testRunner.get() receiveData:150];
    EXPECT_EQ([testRunner.get() waitForUpdatedCompletedUnitCount], 150);
    EXPECT_EQ(testRunner.get().progress.fractionCompleted, 1.5);

    [testRunner.get() finishDownloadTask];
    [testRunner.get() waitForDownloadFinished];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}

// Clients should be able to publish progress on a download that has already started.
TEST(DownloadProgress, PublishProgressOnPartialDownload)
{
    auto testRunner = adoptNS([[DownloadProgressTestRunner alloc] init]);

    [testRunner.get() startDownload:DownloadStartType::ConvertLoadToDownload expectedLength:100];
    [testRunner.get() receiveData:50];

    // Ensure that the the data task has become a download task so that we test
    // telling a live Download, not a PendingDownload, to publish its progress.
    [testRunner.get() waitForDownloadDidCreateDestination];

    [testRunner.get() publishProgress];
    [testRunner.get() subscribeAndWaitForProgress];
    EXPECT_EQ(testRunner.get().progress.completedUnitCount, 50);

    [testRunner.get() receiveData:50];
    EXPECT_EQ([testRunner.get() waitForUpdatedCompletedUnitCount], 100);

    [testRunner.get() finishDownloadTask];
    [testRunner.get() waitForDownloadFinished];
    [testRunner.get() waitToLoseProgress];

    [testRunner.get() tearDown];
}
