/*
 * Copyright (C) 2005 Apple Computer, 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 "WebHistoryItemInternal.h"
#import "WebHistoryItemPrivate.h"

#import "WebFrameBridge.h"
#import "WebFrameInternal.h"
#import "WebFrameView.h"
#import "WebHTMLViewInternal.h"
#import "WebIconDatabase.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebNSDictionaryExtras.h"
#import "WebNSObjectExtras.h"
#import "WebNSURLExtras.h"
#import "WebNSURLRequestExtras.h"
#import "WebNSViewExtras.h"
#import "WebPluginController.h"
#import <JavaScriptCore/Assertions.h>
#import <WebCore/CachedPage.h>
#import <WebCore/HistoryItem.h>
#import <WebCore/Image.h>
#import <WebCore/KURL.h>
#import <WebCore/PageCache.h>
#import <WebCore/PlatformString.h>
#import <WebCore/ThreadCheck.h>
#import <WebCore/WebCoreObjCExtras.h>
#import <WebKitSystemInterface.h>

// Private keys used in the WebHistoryItem's dictionary representation.
// see 3245793 for explanation of "lastVisitedDate"
static NSString *WebLastVisitedTimeIntervalKey = @"lastVisitedDate";
static NSString *WebVisitCountKey = @"visitCount";
static NSString *WebTitleKey = @"title";
static NSString *WebChildrenKey = @"children";
static NSString *WebDisplayTitleKey = @"displayTitle";

// Notification strings.
NSString *WebHistoryItemChangedNotification = @"WebHistoryItemChangedNotification";

using namespace WebCore;

static inline WebHistoryItemPrivate* kitPrivate(WebCoreHistoryItem* list) { return (WebHistoryItemPrivate*)list; }
static inline WebCoreHistoryItem* core(WebHistoryItemPrivate* list) { return (WebCoreHistoryItem*)list; }

HashMap<HistoryItem*, WebHistoryItem*>& historyItemWrappers()
{
    static HashMap<HistoryItem*, WebHistoryItem*> historyItemWrappers;
    return historyItemWrappers;
}

void WKNotifyHistoryItemChanged()
{
    [[NSNotificationCenter defaultCenter]
        postNotificationName:WebHistoryItemChangedNotification object:nil userInfo:nil];
}

@implementation WebHistoryItem

#ifndef BUILDING_ON_TIGER
+ (void)initialize
{
    WebCoreObjCFinalizeOnMainThread(self);
}
#endif

- (id)init
{
    return [self initWithWebCoreHistoryItem:(new HistoryItem)];
}

- (id)initWithURLString:(NSString *)URLString title:(NSString *)title lastVisitedTimeInterval:(NSTimeInterval)time
{
    WebCoreThreadViolationCheck();
    return [self initWithWebCoreHistoryItem:(new HistoryItem(URLString, title, time))];
}

- (void)dealloc
{
    WebCoreThreadViolationCheck();
    if (_private) {
        HistoryItem* coreItem = core(_private);
        coreItem->deref();
        historyItemWrappers().remove(coreItem);
    }
    [super dealloc];
}

- (void)finalize
{
    WebCoreThreadViolationCheck();
    // FIXME: ~HistoryItem is what releases the history item's icon from the icon database
    // It's probably not good to release icons from the database only when the object is garbage-collected. 
    // Need to change design so this happens at a predictable time.
    if (_private) {
        HistoryItem* coreItem = core(_private);
        coreItem->deref();
        historyItemWrappers().remove(coreItem);
    }
    [super finalize];
}

- (id)copyWithZone:(NSZone *)zone
{
    WebCoreThreadViolationCheck();
    WebHistoryItem *copy = (WebHistoryItem *)NSCopyObject(self, 0, zone);
    RefPtr<HistoryItem> item = core(_private)->copy();
    copy->_private = kitPrivate(item.get());
    historyItemWrappers().set(item.release().releaseRef(), copy);
    
    return copy;
}

// FIXME: Need to decide if this class ever returns URLs and decide on the name of this method
- (NSString *)URLString
{
    ASSERT_MAIN_THREAD();
    return nsStringNilIfEmpty(core(_private)->urlString());
}

// The first URL we loaded to get to where this history item points.  Includes both client
// and server redirects.
- (NSString *)originalURLString
{
    ASSERT_MAIN_THREAD();
    return nsStringNilIfEmpty(core(_private)->originalURLString());
}

- (NSString *)title
{
    ASSERT_MAIN_THREAD();
    return nsStringNilIfEmpty(core(_private)->title());
}

- (void)setAlternateTitle:(NSString *)alternateTitle
{
    core(_private)->setAlternateTitle(alternateTitle);
}

- (NSString *)alternateTitle;
{
    return nsStringNilIfEmpty(core(_private)->alternateTitle());
}

- (NSImage *)icon
{
    return [[WebIconDatabase sharedIconDatabase] iconForURL:[self URLString] withSize:WebIconSmallSize];
    
    // FIXME: Ideally, this code should simply be the following -
    // return core(_private)->icon()->getNSImage();
    // Once radar -
    // <rdar://problem/4906567> - NSImage returned from WebCore::Image may be incorrect size
    // is resolved
}

- (NSTimeInterval)lastVisitedTimeInterval
{
    ASSERT_MAIN_THREAD();
    return core(_private)->lastVisitedTime();
}

- (unsigned)hash
{
    return [(NSString*)core(_private)->urlString() hash];
}

- (BOOL)isEqual:(id)anObject
{
    ASSERT_MAIN_THREAD();
    if (![anObject isMemberOfClass:[WebHistoryItem class]]) {
        return NO;
    }
    
    return core(_private)->urlString() == core(((WebHistoryItem*)anObject)->_private)->urlString();
}

- (NSString *)description
{
    ASSERT_MAIN_THREAD();
    HistoryItem* coreItem = core(_private);
    NSMutableString *result = [NSMutableString stringWithFormat:@"%@ %@", [super description], (NSString*)coreItem->urlString()];
    if (coreItem->target()) {
        [result appendFormat:@" in \"%@\"", (NSString*)coreItem->target()];
    }
    if (coreItem->isTargetItem()) {
        [result appendString:@" *target*"];
    }
    if (coreItem->formData()) {
        [result appendString:@" *POST*"];
    }
    
    if (coreItem->children().size()) {
        const HistoryItemVector& children = coreItem->children();
        int currPos = [result length];
        unsigned size = children.size();        
        for (unsigned i = 0; i < size; ++i) {
            WebHistoryItem *child = kit(children[i].get());
            [result appendString:@"\n"];
            [result appendString:[child description]];
        }
        // shift all the contents over.  A bit slow, but hey, this is for debugging.
        NSRange replRange = {currPos, [result length]-currPos};
        [result replaceOccurrencesOfString:@"\n" withString:@"\n    " options:0 range:replRange];
    }
    
    return result;
}

@end

@interface WebWindowWatcher : NSObject
@end


@implementation WebHistoryItem (WebInternal)

HistoryItem* core(WebHistoryItem *item)
{
    if (!item)
        return 0;
    return core(item->_private);
}

WebHistoryItem *kit(HistoryItem* item)
{
    if (!item)
        return nil;
        
    WebHistoryItem *kitItem = historyItemWrappers().get(item);
    if (kitItem)
        return kitItem;
    
    return [[[WebHistoryItem alloc] initWithWebCoreHistoryItem:item] autorelease];
}

+ (WebHistoryItem *)entryWithURL:(NSURL *)URL
{
    return [[[self alloc] initWithURL:URL title:nil] autorelease];
}

static WebWindowWatcher *_windowWatcher = nil;

+ (void)initWindowWatcherIfNecessary
{
    if (_windowWatcher)
        return;
    _windowWatcher = [[WebWindowWatcher alloc] init];
    [[NSNotificationCenter defaultCenter] addObserver:_windowWatcher selector:@selector(windowWillClose:)
        name:NSWindowWillCloseNotification object:nil];
}

- (id)initWithURL:(NSURL *)URL target:(NSString *)target parent:(NSString *)parent title:(NSString *)title
{
    return [self initWithWebCoreHistoryItem:(new HistoryItem(URL, target, parent, title))];
}

- (id)initWithURLString:(NSString *)URLString title:(NSString *)title displayTitle:(NSString *)displayTitle lastVisitedTimeInterval:(NSTimeInterval)time
{
    return [self initWithWebCoreHistoryItem:(new HistoryItem(URLString, title, displayTitle, time))];
}

- (id)initWithWebCoreHistoryItem:(PassRefPtr<HistoryItem>)item
{   
    WebCoreThreadViolationCheck();
    // Need to tell WebCore what function to call for the 
    // "History Item has Changed" notification - no harm in doing this
    // everytime a WebHistoryItem is created
    // Note: We also do this in [WebFrameView initWithFrame:] where we do
    // other "init before WebKit is used" type things
    WebCore::notifyHistoryItemChanged = WKNotifyHistoryItemChanged;
    
    self = [super init];
    
    _private = kitPrivate(item.releaseRef());
    ASSERT(!historyItemWrappers().get(core(_private)));
    historyItemWrappers().set(core(_private), self);
    return self;
}

- (void)setTitle:(NSString *)title
{
    core(_private)->setTitle(title);
}

- (void)setVisitCount:(int)count
{
    core(_private)->setVisitCount(count);
}

- (void)setViewState:(id)statePList;
{
    core(_private)->setViewState(statePList);
}

- (void)_mergeAutoCompleteHints:(WebHistoryItem *)otherItem
{
    ASSERT_ARG(otherItem, otherItem);
    core(_private)->mergeAutoCompleteHints(core(otherItem->_private));
}

- (id)initFromDictionaryRepresentation:(NSDictionary *)dict
{
    ASSERT_MAIN_THREAD();
    NSString *URLString = [dict _webkit_stringForKey:@""];
    NSString *title = [dict _webkit_stringForKey:WebTitleKey];

    // Do an existence check to avoid calling doubleValue on a nil string. Leave
    // time interval at 0 if there's no value in dict.
    NSString *timeIntervalString = [dict _webkit_stringForKey:WebLastVisitedTimeIntervalKey];
    NSTimeInterval lastVisited = timeIntervalString == nil ? 0 : [timeIntervalString doubleValue];

    self = [self initWithURLString:URLString title:title displayTitle:[dict _webkit_stringForKey:WebDisplayTitleKey] lastVisitedTimeInterval:lastVisited];
    
    // Check if we've read a broken URL from the file that has non-Latin1 chars.  If so, try to convert
    // as if it was from user typing.
    if (![URLString canBeConvertedToEncoding:NSISOLatin1StringEncoding]) {
        NSURL *tempURL = [NSURL _web_URLWithUserTypedString:URLString];
        ASSERT(tempURL);
        NSString *newURLString = [tempURL _web_originalDataAsString];
        core(_private)->setURLString(newURLString);
        core(_private)->setOriginalURLString(newURLString);
    } 

    core(_private)->setVisitCount([dict _webkit_intForKey:WebVisitCountKey]);

    NSArray *childDicts = [dict objectForKey:WebChildrenKey];
    if (childDicts) {
        for (int i = [childDicts count]; i >= 0; i--) {
            WebHistoryItem *child = [[WebHistoryItem alloc] initFromDictionaryRepresentation: [childDicts objectAtIndex:i]];
            core(_private)->addChildItem(core(child->_private));
            [child release];
        }
    }

    return self;
}

- (NSPoint)scrollPoint
{
    ASSERT_MAIN_THREAD();
    return core(_private)->scrollPoint();
}

@end

@implementation WebHistoryItem (WebPrivate)

- (id)initWithURL:(NSURL *)URL title:(NSString *)title
{
    return [self initWithURLString:[URL _web_originalDataAsString] title:title lastVisitedTimeInterval:0];
}

- (NSDictionary *)dictionaryRepresentation
{
    ASSERT_MAIN_THREAD();
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:6];

    HistoryItem* coreItem = core(_private);
    
    if (!coreItem->urlString().isEmpty()) {
        [dict setObject:(NSString*)coreItem->urlString() forKey:@""];
    }
    if (!coreItem->title().isEmpty()) {
        [dict setObject:(NSString*)coreItem->title() forKey:WebTitleKey];
    }
    if (!coreItem->alternateTitle().isEmpty()) {
        [dict setObject:(NSString*)coreItem->alternateTitle() forKey:WebDisplayTitleKey];
    }
    if (coreItem->lastVisitedTime() != 0.0) {
        // store as a string to maintain backward compatibility (see 3245793)
        [dict setObject:[NSString stringWithFormat:@"%.1lf", coreItem->lastVisitedTime()]
                 forKey:WebLastVisitedTimeIntervalKey];
    }
    if (coreItem->visitCount()) {
        [dict setObject:[NSNumber numberWithInt:coreItem->visitCount()] forKey:WebVisitCountKey];
    }
    if (coreItem->children().size()) {
        const HistoryItemVector& children = coreItem->children();
        NSMutableArray *childDicts = [NSMutableArray arrayWithCapacity:children.size()];
        
        for (int i = children.size(); i >= 0; i--)
            [childDicts addObject:[kit(children[i].get()) dictionaryRepresentation]];
        [dict setObject: childDicts forKey:WebChildrenKey];
    }

    return dict;
}

- (NSString *)target
{
    ASSERT_MAIN_THREAD();
    return nsStringNilIfEmpty(core(_private)->target());
}

- (BOOL)isTargetItem
{
    return core(_private)->isTargetItem();
}

- (int)visitCount
{
    ASSERT_MAIN_THREAD();
    return core(_private)->visitCount();
}

- (NSString *)RSSFeedReferrer
{
    return nsStringNilIfEmpty(core(_private)->rssFeedReferrer());
}

- (void)setRSSFeedReferrer:(NSString *)referrer
{
    core(_private)->setRSSFeedReferrer(referrer);
}

- (NSArray *)children
{
    ASSERT_MAIN_THREAD();
    const HistoryItemVector& children = core(_private)->children();
    if (!children.size())
        return nil;

    unsigned size = children.size();
    NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:size] autorelease];
    
    for (unsigned i = 0; i < size; ++i)
        [result addObject:kit(children[i].get())];
    
    return result;
}

- (void)setAlwaysAttemptToUsePageCache:(BOOL)flag
{
    // Safari 2.0 uses this for SnapBack, so we stub it out to avoid a crash.
}

- (NSURL *)URL
{
    ASSERT_MAIN_THREAD();
    KURL url = core(_private)->url();
    return url.isEmpty() ? nil : url.getNSURL();
}

// This should not be called directly for WebHistoryItems that are already included
// in WebHistory. Use -[WebHistory setLastVisitedTimeInterval:forItem:] instead.
- (void)_setLastVisitedTimeInterval:(NSTimeInterval)time
{
    core(_private)->setLastVisitedTime(time);
}

// FIXME: <rdar://problem/4880065> - Push Global History into WebCore
// Once that task is complete, this accessor can go away
- (NSCalendarDate *)_lastVisitedDate
{
    ASSERT_MAIN_THREAD();
    return [[[NSCalendarDate alloc] initWithTimeIntervalSinceReferenceDate:core(_private)->lastVisitedTime()] autorelease];
}

- (WebHistoryItem *)targetItem
{    
    ASSERT_MAIN_THREAD();
    HistoryItem* coreItem = core(_private);
    if (coreItem->isTargetItem() || !coreItem->hasChildren())
        return self;
    return kit(coreItem->recurseToFindTargetItem());
}

+ (void)_releaseAllPendingPageCaches
{
    pageCache()->releaseAutoreleasedPagesNow();
}

- (id)_transientPropertyForKey:(NSString *)key
{
    return core(_private)->getTransientProperty(key);
}

- (void)_setTransientProperty:(id)property forKey:(NSString *)key
{
    core(_private)->setTransientProperty(key, property);
}

@end


// FIXME: <rdar://problem/4886761>
// This is a bizarre policy - we flush the page caches ANY time ANY window is closed?  
@implementation WebWindowWatcher
-(void)windowWillClose:(NSNotification *)notification
{
    pageCache()->releaseAutoreleasedPagesNow();
}
@end
