/*
 * Copyright (C) 2005, 2006, 2007 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 Computer, 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 "WebResourcePrivate.h"

#import "WebFrameBridge.h"
#import "WebNSDictionaryExtras.h"
#import "WebNSURLExtras.h"
#import <WebCore/WebCoreURLResponse.h>

static NSString * const WebResourceDataKey =              @"WebResourceData";
static NSString * const WebResourceFrameNameKey =         @"WebResourceFrameName";
static NSString * const WebResourceMIMETypeKey =          @"WebResourceMIMEType";
static NSString * const WebResourceURLKey =               @"WebResourceURL";
static NSString * const WebResourceTextEncodingNameKey =  @"WebResourceTextEncodingName";
static NSString * const WebResourceResponseKey =          @"WebResourceResponse";

#define WebResourceVersion 1

@interface WebResourcePrivate : NSObject
{
@public
    NSData *data;
    NSURL *URL;
    NSString *frameName;
    NSString *MIMEType;
    NSString *textEncodingName;
    NSURLResponse *response;
    BOOL shouldIgnoreWhenUnarchiving;
}
@end

@implementation WebResourcePrivate

- (void)dealloc
{
    [data release];
    [URL release];
    [frameName release];
    [MIMEType release];
    [textEncodingName release];
    [response release];
    [super dealloc];
}

@end

@implementation WebResource

- (id)init
{
    self = [super init];
    if (!self)
        return nil;
    _private = [[WebResourcePrivate alloc] init];
    return self;
}

- (id)initWithData:(NSData *)data URL:(NSURL *)URL MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName frameName:(NSString *)frameName
{
    return [self _initWithData:data URL:URL MIMEType:MIMEType textEncodingName:textEncodingName frameName:frameName response:nil copyData:YES];
}

- (id)initWithCoder:(NSCoder *)decoder
{
    self = [self init];
    if (!self)
        return nil;

    @try {
        id object = [decoder decodeObjectForKey:WebResourceDataKey];
        if ([object isKindOfClass:[NSData class]])
            _private->data = [object retain];
        object = [decoder decodeObjectForKey:WebResourceURLKey];
        if ([object isKindOfClass:[NSURL class]])
            _private->URL = [object retain];
        object = [decoder decodeObjectForKey:WebResourceMIMETypeKey];
        if ([object isKindOfClass:[NSString class]])
            _private->MIMEType = [object retain];
        object = [decoder decodeObjectForKey:WebResourceTextEncodingNameKey];
        if ([object isKindOfClass:[NSString class]])
            _private->textEncodingName = [object retain];
        object = [decoder decodeObjectForKey:WebResourceFrameNameKey];
        if ([object isKindOfClass:[NSString class]])
            _private->frameName = [object retain];
        object = [decoder decodeObjectForKey:WebResourceResponseKey];
        if ([object isKindOfClass:[NSURLResponse class]])
            _private->response = [object retain];
    } @catch(id) {
        [self release];
        return nil;
    }

    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject:_private->data forKey:WebResourceDataKey];
    [encoder encodeObject:_private->URL forKey:WebResourceURLKey];
    [encoder encodeObject:_private->MIMEType forKey:WebResourceMIMETypeKey];
    [encoder encodeObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];
    [encoder encodeObject:_private->frameName forKey:WebResourceFrameNameKey];
    [encoder encodeObject:_private->response forKey:WebResourceResponseKey];
}

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

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

- (NSData *)data
{
    return _private->data;
}

- (NSURL *)URL
{
    return _private->URL;
}

- (NSString *)MIMEType
{
    return _private->MIMEType;
}

- (NSString *)textEncodingName
{
    return _private->textEncodingName;
}

- (NSString *)frameName
{
    return _private->frameName;
}

- (id)description
{
    return [NSString stringWithFormat:@"<%@ %@>", [self className], [self URL]];
}

@end

@implementation WebResource (WebResourcePrivate)

// SPI for Mail (5066325)
- (void)_ignoreWhenUnarchiving
{
    _private->shouldIgnoreWhenUnarchiving = YES;
}

- (BOOL)_shouldIgnoreWhenUnarchiving
{
    return _private->shouldIgnoreWhenUnarchiving;
}

+ (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists
{
    if (![propertyLists isKindOfClass:[NSArray class]]) {
        return nil;
    }
    NSEnumerator *enumerator = [propertyLists objectEnumerator];
    NSMutableArray *resources = [NSMutableArray array];
    NSDictionary *propertyList;
    while ((propertyList = [enumerator nextObject]) != nil) {
        WebResource *resource = [[WebResource alloc] _initWithPropertyList:propertyList];
        if (resource) {
            [resources addObject:resource];
            [resource release];
        }
    }
    return resources;
}

+ (NSArray *)_propertyListsFromResources:(NSArray *)resources
{
    NSEnumerator *enumerator = [resources objectEnumerator];
    NSMutableArray *propertyLists = [NSMutableArray array];
    WebResource *resource;
    while ((resource = [enumerator nextObject]) != nil) {
        [propertyLists addObject:[resource _propertyListRepresentation]];
    }
    return propertyLists;
}

- (id)_initWithData:(NSData *)data 
                URL:(NSURL *)URL 
           MIMEType:(NSString *)MIMEType 
   textEncodingName:(NSString *)textEncodingName 
          frameName:(NSString *)frameName 
           response:(NSURLResponse *)response
           copyData:(BOOL)copyData
{
    [self init];    
    
    if (!data) {
        [self release];
        return nil;
    }
    _private->data = copyData ? [data copy] : [data retain];
    
    if (!URL) {
        [self release];
        return nil;
    }
    _private->URL = [URL copy];
    
    if (!MIMEType) {
        [self release];
        return nil;
    }
    _private->MIMEType = [MIMEType copy];
    
    _private->textEncodingName = [textEncodingName copy];
    _private->frameName = [frameName copy];
    _private->response = [response retain];
        
    return self;
}

- (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response
{
    // Pass NO for copyData since the data doesn't need to be copied since we know that callers will no longer modify it.
    // Copying it will also cause a performance regression.
    return [self _initWithData:data
                           URL:URL
                      MIMEType:[response _webcore_MIMEType]
              textEncodingName:[response textEncodingName]
                     frameName:nil
                      response:response
                      copyData:NO];    
}

- (id)_initWithPropertyList:(id)propertyList
{
    if (![propertyList isKindOfClass:[NSDictionary class]]) {
        [self release];
        return nil;
    }
    
    NSURLResponse *response = nil;
    NSData *responseData = [propertyList objectForKey:WebResourceResponseKey];
    if ([responseData isKindOfClass:[NSData class]]) {
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData];
        @try {
            id responseObject = [unarchiver decodeObjectForKey:WebResourceResponseKey];
            if ([responseObject isKindOfClass:[NSURLResponse class]])
                response = responseObject;
            [unarchiver finishDecoding];
        } @catch(id) {
            response = nil;
        }
        [unarchiver release];
    }

    NSData *data = [propertyList objectForKey:WebResourceDataKey];
    NSString *URLString = [propertyList _webkit_stringForKey:WebResourceURLKey];
    return [self _initWithData:[data isKindOfClass:[NSData class]] ? data : nil
                           URL:URLString ? [NSURL _web_URLWithDataAsString:URLString] : nil
                      MIMEType:[propertyList _webkit_stringForKey:WebResourceMIMETypeKey]
              textEncodingName:[propertyList _webkit_stringForKey:WebResourceTextEncodingNameKey]
                     frameName:[propertyList _webkit_stringForKey:WebResourceFrameNameKey]
                      response:response
                      copyData:NO];
}

- (NSFileWrapper *)_fileWrapperRepresentation
{
    NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:_private->data] autorelease];
    NSString *preferredFilename = [_private->response suggestedFilename];
    if (!preferredFilename || ![preferredFilename length])
        preferredFilename = [_private->URL _webkit_suggestedFilenameWithMIMEType:_private->MIMEType];
    [wrapper setPreferredFilename:preferredFilename];
    return wrapper;
}

- (id)_propertyListRepresentation
{
    NSMutableDictionary *propertyList = [NSMutableDictionary dictionary];
    [propertyList setObject:_private->data forKey:WebResourceDataKey];
    [propertyList setObject:[_private->URL _web_originalDataAsString] forKey:WebResourceURLKey];
    [propertyList setObject:_private->MIMEType forKey:WebResourceMIMETypeKey];
    if (_private->textEncodingName != nil) {
        [propertyList setObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];
    }
    if (_private->frameName != nil) {
        [propertyList setObject:_private->frameName forKey:WebResourceFrameNameKey];
    }    
    if (_private->response != nil) {
        NSMutableData *responseData = [[NSMutableData alloc] init];
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData];
        [archiver encodeObject:_private->response forKey:WebResourceResponseKey];
        [archiver finishEncoding];
        [archiver release];
        [propertyList setObject:responseData forKey:WebResourceResponseKey];
        [responseData release];
    }        
    return propertyList;
}

- (NSURLResponse *)_response
{
    if (_private->response != nil) {
        return _private->response;
    }
    return [[[NSURLResponse alloc] initWithURL:_private->URL
                                      MIMEType:_private->MIMEType 
                         expectedContentLength:[_private->data length]
                              textEncodingName:_private->textEncodingName] autorelease];
}

- (NSString *)_stringValue
{
    NSString *textEncodingName = [self textEncodingName];
    return [WebFrameBridge stringWithData:_private->data textEncodingName:textEncodingName];
}

@end
