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

#import <WebKit/WKBrowsingContextController.h>
#import <wtf/NeverDestroyed.h>
#import <wtf/RetainPtr.h>

#if PLATFORM(IOS_FAMILY)
#import <MobileCoreServices/MobileCoreServices.h>
#endif

static RetainPtr<NSString>& testScheme()
{
    static NeverDestroyed<RetainPtr<NSString>> _testScheme;
    return _testScheme;
}

@implementation TestProtocol

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

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

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

+ (NSString *)scheme
{
    return testScheme().get();
}

+ (void)registerWithScheme:(NSString *)scheme
{
    testScheme() = scheme;
    [NSURLProtocol registerClass:[self class]];
    [WKBrowsingContextController registerSchemeForCustomProtocol:scheme];
}

+ (void)unregister
{
    [WKBrowsingContextController unregisterSchemeForCustomProtocol:testScheme().get()];
    [NSURLProtocol unregisterClass:[self class]];
    testScheme() = nil;
}

static RetainPtr<NSDictionary<NSString *, NSString *>>& additionalResponseHeaders()
{
    static NeverDestroyed<RetainPtr<NSDictionary<NSString *, NSString *>>> _additionalResponseHeaders;
    return _additionalResponseHeaders;
}

+ (NSDictionary<NSString *, NSString *> *)additionalResponseHeaders
{
    return additionalResponseHeaders().get();
}

+ (void)setAdditionalResponseHeaders:(NSDictionary<NSString *, NSString *> *)additionalHeaders
{
    additionalResponseHeaders() = adoptNS([additionalHeaders copy]);
}

static NSURL *createRedirectURL(NSString *query)
{
    return [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", testScheme().get(), query]];
}

static NSString *contentTypeForFileExtension(NSString *fileExtension)
{
    auto identifier = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, nullptr));
    auto mimeType = adoptCF(UTTypeCopyPreferredTagWithClass(identifier.get(), kUTTagClassMIMEType));
    return (__bridge NSString *)mimeType.autorelease();
}

- (void)startLoading
{
    NSURL *requestURL = self.request.URL;
    EXPECT_TRUE([requestURL.scheme isEqualToString:testScheme().get()]);

    if ([requestURL.host isEqualToString:@"307-redirect"]) {
        RetainPtr<NSHTTPURLResponse> response = adoptNS([[NSHTTPURLResponse alloc] initWithURL:requestURL statusCode:307 HTTPVersion:@"HTTP/1.1" headerFields:@{@"Content-Type" : @"text/html"}]);
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:createRedirectURL(requestURL.query)];
        request.HTTPMethod = self.request.HTTPMethod;
        [self.client URLProtocol:self wasRedirectedToRequest:request redirectResponse:response.get()];
        return;
    }

    if ([requestURL.host isEqualToString:@"redirect"]) {
        NSData *data = [@"PASS" dataUsingEncoding:NSASCIIStringEncoding];
        auto response = adoptNS([[NSURLResponse alloc] initWithURL:requestURL MIMEType:@"text/html" expectedContentLength:data.length textEncodingName:nil]);
        [self.client URLProtocol:self wasRedirectedToRequest:[NSURLRequest requestWithURL:createRedirectURL(requestURL.query)] redirectResponse:response.get()];
        return;
    }

    NSString *contentType;
    NSData *data;
    if ([requestURL.host isEqualToString:@"bundle-file"]) {
        NSString *fileName = requestURL.lastPathComponent;
        NSString *fileExtension = fileName.pathExtension;
        contentType = contentTypeForFileExtension(fileExtension);
        data = [NSData dataWithContentsOfURL:[NSBundle.mainBundle URLForResource:fileName.stringByDeletingPathExtension withExtension:fileExtension subdirectory:@"TestWebKitAPI.resources"]];
    } else {
        contentType = @"text/html";
        data = [@"PASS" dataUsingEncoding:NSASCIIStringEncoding];
    }

    NSMutableDictionary *responseHeaders = [NSMutableDictionary dictionaryWithCapacity:2];
    responseHeaders[@"Content-Type"] = contentType;
    responseHeaders[@"Content-Length"] = [NSString stringWithFormat:@"%tu", data.length];
    if (auto& headers = additionalResponseHeaders())
        [responseHeaders addEntriesFromDictionary:headers.get()];

    auto response = adoptNS([[NSHTTPURLResponse alloc] initWithURL:requestURL statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:responseHeaders]);

    [self.client URLProtocol:self didReceiveResponse:response.get() cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [self.client URLProtocol:self didLoadData:data];
    [self.client URLProtocolDidFinishLoading:self];
}

- (void)stopLoading
{
}

@end
