/*
 * 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 <sys/xattr.h>
#import <wtf/BlockPtr.h>
#import <wtf/FileSystem.h>
#import <wtf/RetainPtr.h>
#import <wtf/WeakObjCPtr.h>

@class DownloadProgressTestProtocol;

enum class DownloadStartType {
    ConvertLoadToDownload,
    StartFromNavigationAction,
};

@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];
    [NSFileManager.defaultManager createFileAtPath:m_progressURL.get().path contents:nil attributes:nil];

    currentTestRunner = self;

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

    return self;
}

- (void)dealloc
{
    [NSFileManager.defaultManager removeItemAtURL:m_progressURL.get() error:nil];

    [super dealloc];
}

- (_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 HAVE(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 HAVE(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;
    }

    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);
}

- (NSURL *)progressURL
{
    return m_progressURL.get();
}

- (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(WKNavigationResponsePolicyDownload);
    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());

    RetainPtr path = FileSystem::createTemporaryFile("TestWebKitAPI"_s).createNSString();
    EXPECT_TRUE(path && [path.get() length]);

    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];
}

// 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() waitForDownloadFailed];
    [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];
}

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

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

    char xattrValue[10] = { 0 };
    auto size = getxattr(testRunner.get().progressURL.fileSystemRepresentation, "com.apple.progress.fractionCompleted", xattrValue, sizeof(xattrValue), 0, 0);

    EXPECT_EQ(size, 5);
    EXPECT_STREQ(xattrValue, "0.600");

    [testRunner.get() tearDown];
}
