/*
 * Copyright (C) 2005, 2006, 2007, 2008 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. 
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "WebArchive.h"
#import "WebArchiveInternal.h"

#import "WebKitLogging.h"
#import "WebNSObjectExtras.h"
#import "WebResourceInternal.h"
#import "WebTypesInternal.h"
#import <JavaScriptCore/InitializeThreading.h>
#import <WebCore/ArchiveResource.h>
#import <WebCore/LegacyWebArchive.h>
#import <WebCore/ThreadCheck.h>
#import <WebCore/WebCoreObjCExtras.h>
#import <wtf/MainThread.h>
#import <wtf/RunLoop.h>

using namespace WebCore;

NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type";

static NSString * const WebMainResourceKey = @"WebMainResource";
static NSString * const WebSubresourcesKey = @"WebSubresources";
static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives";

@interface WebArchivePrivate : NSObject {
@public
    WebResource *cachedMainResource;
    NSArray *cachedSubresources;
    NSArray *cachedSubframeArchives;
@private
    RefPtr<LegacyWebArchive> coreArchive;
}

- (instancetype)initWithCoreArchive:(RefPtr<LegacyWebArchive>&&)coreArchive;
- (LegacyWebArchive*)coreArchive;
- (void)setCoreArchive:(Ref<LegacyWebArchive>&&)newCoreArchive;
@end

@implementation WebArchivePrivate

+ (void)initialize
{
#if !PLATFORM(IOS_FAMILY)
    JSC::initializeThreading();
    RunLoop::initializeMainRunLoop();
#endif
}

- (instancetype)init
{
    self = [super init];
    if (!self)
        return nil;
    coreArchive = LegacyWebArchive::create();
    return self;
}

- (instancetype)initWithCoreArchive:(RefPtr<LegacyWebArchive>&&)_coreArchive
{
    self = [super init];
    if (!self|| !_coreArchive) {
        [self release];
        return nil;
    }
    coreArchive = WTFMove(_coreArchive);
    return self;
}

- (LegacyWebArchive*)coreArchive
{
    return coreArchive.get();
}

- (void)setCoreArchive:(Ref<LegacyWebArchive>&&)newCoreArchive
{
    ASSERT(coreArchive);
    coreArchive = WTFMove(newCoreArchive);
}

- (void)dealloc
{
    if (WebCoreObjCScheduleDeallocateOnMainThread([WebArchivePrivate class], self))
        return;
    
    [cachedMainResource release];
    [cachedSubresources release];
    [cachedSubframeArchives release];
    
    [super dealloc];
}

@end

@implementation WebArchive

- (instancetype)init
{
    WebCoreThreadViolationCheckRoundTwo();

    self = [super init];
    if (!self)
        return nil;
    _private = [[WebArchivePrivate alloc] init];
    return self;
}

static BOOL isArrayOfClass(id object, Class elementClass)
{
    if (![object isKindOfClass:[NSArray class]])
        return NO;
    NSArray *array = (NSArray *)object;
    NSUInteger count = [array count];
    for (NSUInteger i = 0; i < count; ++i)
        if (![[array objectAtIndex:i] isKindOfClass:elementClass])
            return NO;
    return YES;
}

- (instancetype)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives
{
    WebCoreThreadViolationCheckRoundTwo();

    self = [super init];
    if (!self)
        return nil;

    _private = [[WebArchivePrivate alloc] init];

    _private->cachedMainResource = [mainResource retain];
    if (!_private->cachedMainResource) {
        [self release];
        return nil;
    }
    
    if (!subresources || isArrayOfClass(subresources, [WebResource class]))
        _private->cachedSubresources = [subresources retain];
    else {
        [self release];
        return nil;
    }

    if (!subframeArchives || isArrayOfClass(subframeArchives, [WebArchive class]))
        _private->cachedSubframeArchives = [subframeArchives retain];
    else {
        [self release];
        return nil;
    }

    Vector<Ref<ArchiveResource>> coreResources;
    for (WebResource *subresource in subresources)
        coreResources.append([subresource _coreResource]);

    Vector<Ref<LegacyWebArchive>> coreArchives;
    for (WebArchive *subframeArchive in subframeArchives)
        coreArchives.append(*[subframeArchive->_private coreArchive]);

    [_private setCoreArchive:LegacyWebArchive::create([mainResource _coreResource], WTFMove(coreResources), WTFMove(coreArchives))];
    return self;
}

- (instancetype)initWithData:(NSData *)data
{
    WebCoreThreadViolationCheckRoundTwo();

    self = [super init];
    if (!self)
        return nil;
        
#if !LOG_DISABLED
    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
#endif

    _private = [[WebArchivePrivate alloc] init];
    auto coreArchive = LegacyWebArchive::create(SharedBuffer::create(data));
    if (!coreArchive) {
        [self release];
        return nil;
    }
        
    [_private setCoreArchive:coreArchive.releaseNonNull()];
        
#if !LOG_DISABLED
    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
    CFAbsoluteTime duration = end - start;
#endif
    LOG(Timing, "Parsing web archive with [NSPropertyListSerialization propertyListFromData::::] took %f seconds", duration);
    
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)decoder
{    
    WebResource *mainResource = nil;
    NSArray *subresources = nil;
    NSArray *subframeArchives = nil;
    
    @try {
        id object = [decoder decodeObjectForKey:WebMainResourceKey];
        if ([object isKindOfClass:[WebResource class]])
            mainResource = object;
        object = [decoder decodeObjectForKey:WebSubresourcesKey];
        if (isArrayOfClass(object, [WebResource class]))
            subresources = object;
        object = [decoder decodeObjectForKey:WebSubframeArchivesKey];
        if (isArrayOfClass(object, [WebArchive class]))
            subframeArchives = object;
    } @catch(id) {
        [self release];
        return nil;
    }

    return [self initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives];
}

- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:[self mainResource] forKey:WebMainResourceKey];
    [encoder encodeObject:[self subresources] forKey:WebSubresourcesKey];
    [encoder encodeObject:[self subframeArchives] forKey:WebSubframeArchivesKey];    
}

- (void)dealloc
{
    [_private release];
    [super dealloc];
}

- (id)copyWithZone:(NSZone *)zone
{
    return [self retain];
}

- (WebResource *)mainResource
{
    WebCoreThreadViolationCheckRoundTwo();

    // Currently from WebKit API perspective, WebArchives are entirely immutable once created
    // If they ever become mutable, we'll need to rethink this. 
    if (!_private->cachedMainResource) {
        if (auto* coreArchive = [_private coreArchive]) {
            if (auto* mainResource = coreArchive->mainResource())
                _private->cachedMainResource = [[WebResource alloc] _initWithCoreResource:*mainResource];
        }
    }
    
    return [[_private->cachedMainResource retain] autorelease];
}

- (NSArray *)subresources
{
    WebCoreThreadViolationCheckRoundTwo();

    // Currently from WebKit API perspective, WebArchives are entirely immutable once created
    // If they ever become mutable, we'll need to rethink this.     
    if (!_private->cachedSubresources) {
        LegacyWebArchive* coreArchive = [_private coreArchive];
        if (!coreArchive)
            _private->cachedSubresources = [[NSArray alloc] init];
        else {
            auto& subresources = coreArchive->subresources();
            NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:subresources.size()];
            _private->cachedSubresources = mutableArray;
            for (auto& subresource : subresources) {
                if (WebResource *resource = [[WebResource alloc] _initWithCoreResource:subresource.get()]) {
                    [mutableArray addObject:resource];
                    [resource release];
                }
            }
        }
    }
    // Maintain the WebKit 3 behavior of this API, which is documented and
    // relied upon by some clients, of returning nil if there are no subresources.
    return [_private->cachedSubresources count] ? [[_private->cachedSubresources retain] autorelease] : nil;
}

- (NSArray *)subframeArchives
{
    WebCoreThreadViolationCheckRoundTwo();

    // Currently from WebKit API perspective, WebArchives are entirely immutable once created
    // If they ever become mutable, we'll need to rethink this.  
    if (!_private->cachedSubframeArchives) {
        auto* coreArchive = [_private coreArchive];
        if (!coreArchive)
            _private->cachedSubframeArchives = [[NSArray alloc] init];
        else {
            auto& subframeArchives = coreArchive->subframeArchives();
            auto mutableArray = [[NSMutableArray alloc] initWithCapacity:subframeArchives.size()];
            _private->cachedSubframeArchives = mutableArray;
            for (unsigned i = 0; i < subframeArchives.size(); ++i) {
                WebArchive *archive = [[WebArchive alloc] _initWithCoreLegacyWebArchive:static_cast<LegacyWebArchive*>(subframeArchives[i].ptr())];
                [mutableArray addObject:archive];
                [archive release];
            }
        }
    }
    
    return [[_private->cachedSubframeArchives retain] autorelease];
}

- (NSData *)data
{
    WebCoreThreadViolationCheckRoundTwo();

#if !LOG_DISABLED
    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
#endif

    RetainPtr<CFDataRef> data = [_private coreArchive]->rawDataRepresentation();
    
#if !LOG_DISABLED
    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
    CFAbsoluteTime duration = end - start;
#endif
    LOG(Timing, "Serializing web archive to raw CFPropertyList data took %f seconds", duration);
        
    return [[(NSData *)data.get() retain] autorelease];
}

@end

@implementation WebArchive (WebInternal)

- (id)_initWithCoreLegacyWebArchive:(RefPtr<WebCore::LegacyWebArchive>&&)coreLegacyWebArchive
{
    WebCoreThreadViolationCheckRoundTwo();

    self = [super init];
    if (!self)
        return nil;
    
    _private = [[WebArchivePrivate alloc] initWithCoreArchive:WTFMove(coreLegacyWebArchive)];
    if (!_private) {
        [self release];
        return nil;
    }

    return self;
}

- (WebCore::LegacyWebArchive *)_coreLegacyWebArchive
{
    WebCoreThreadViolationCheckRoundTwo();

    return [_private coreArchive];
}

@end
