/*
**  LocalFolderCacheManager.m
**
**  Copyright (c) 2001, 2002
**
**  Author: Ludovic Marcotte <ludovic@Sophos.ca>
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**  
**  This library is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
**  Lesser General Public License for more details.
**  
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <Pantomime/LocalFolderCacheManager.h>

#include <Pantomime/Constants.h>
#include <Pantomime/LocalFolder.h>
#include <Pantomime/LocalMessage.h>

#include <Foundation/NSArchiver.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSException.h>
#include <Foundation/NSFileManager.h>
#include <Foundation/NSValue.h>

@implementation LocalFolderCacheManager

- (id) init
{
  self = [super init];
  
  messages = [[NSMutableArray alloc] init];
  
  [self setModificationDate: [NSDate date]];
  [self setFileSize: 0];

  return self;
}

- (id) initWithPath: (NSString *) thePath
{
  self = [self init];
  
  [self setPathToCache: thePath];

  return self;
}


- (void) dealloc
{
  //NSDebugLog(@"LocalFolderCacheManager: -dealloc");

  RELEASE(pathToCache);
  RELEASE(messages);
  RELEASE(modificationDate);

  [super dealloc];
}


- (BOOL) synchronize
{
  NSDictionary *attributes;

  //NSDebugLog(@"LocalFolderCacheManager: -synchronize");
  
  attributes = [[NSFileManager defaultManager] fileAttributesAtPath: [self pathToFolder]
					       traverseLink: YES];
  
  [self setModificationDate: [attributes objectForKey: NSFileModificationDate]];
  [self setFileSize: [[attributes objectForKey: NSFileSize] intValue]];
  
  return [NSArchiver archiveRootObject: self toFile: [self pathToCache]];
}

//
// NSCoding protocol
//

- (void) encodeWithCoder: (NSCoder *) theCoder
{
  [theCoder encodeObject: [self modificationDate]];
  [theCoder encodeObject: [NSNumber numberWithInt: [self fileSize]]];
  [theCoder encodeObject: [self messages]];
}

- (id) initWithCoder: (NSCoder *) theCoder
{
  self = [super init]; 
  
  [self setModificationDate: [theCoder decodeObject]];
  [self setFileSize: [[theCoder decodeObject] intValue]];
  [self setMessages: [theCoder decodeObject]];
  
  return self;
}


//
// access/mutation methods
//

- (NSDate *) modificationDate
{
  return modificationDate;
}

- (void) setModificationDate: (NSDate *) theDate
{
  RETAIN(theDate);
  RELEASE(modificationDate);
  modificationDate = theDate;
}

- (int) fileSize
{
  return fileSize;
}

- (void) setFileSize: (int) theSize
{
  fileSize = theSize;
}

- (void) addMessage: (LocalMessage *) theMessage
{
  //NSDebugLog(@"Adding a message to the cache...");
  if ( theMessage )
    {
      [messages addObject: theMessage];
    }
  else
    {
      NSDebugLog(@"Error in LocalFolderCacheManager: -addMessage. Attempted to add a nil.");
    }
}

- (void) removeMessage: (LocalMessage *) theMessage
{
  if ( theMessage )
    {
      [messages removeObject: theMessage];
    }
  else
    {
      NSDebugLog(@"Error in LocalFolderCacheManager: -removeMessage. Attempted to remove a nil.");
    }
}

- (NSArray *) messages
{
  return messages;
}

- (void) setMessages: (NSArray *) theMessages
{
  if ( theMessages )
    {
      RELEASE(messages);
      messages = [[NSMutableArray alloc] initWithArray: theMessages];
    }
  else
    {
      RELEASE(messages);
      messages = nil;
    }
}


- (NSString *) pathToCache
{
  return pathToCache;
}

- (void) setPathToCache: (NSString *) thePathToCache
{
  RETAIN(thePathToCache);
  RELEASE(pathToCache);
  pathToCache = thePathToCache;
}


- (NSString *) pathToFolder
{
  return pathToFolder;
}


//
// We don't need to retain this ivar since it's retained in the folder object
// already.
//
- (void) setPathToFolder: (NSString *) thePathToFolder
{
  pathToFolder = thePathToFolder;
}

//
// Other methods
//
- (void) invalidate
{
  [messages removeAllObjects];
}



//
// class methods
//
+ (id) localFolderCacheFromDiskWithPath: (NSString *) thePath;
{
  LocalFolderCacheManager *aLocalFolderCacheManager;

  // Get the cache. Do it in an exception handling block,
  // so that in case the cache format has changed, we will catch it,
  // and automatically rebuild our cache.
  NS_DURING
    aLocalFolderCacheManager = [NSUnarchiver unarchiveObjectWithFile: thePath ];
  NS_HANDLER
    NSLog(@"Caught exception retrieving cache. Format may have changed, rebuilding!");
    aLocalFolderCacheManager = nil;
  NS_ENDHANDLER
    
  if ( aLocalFolderCacheManager )
    {
      NSDebugLog(@"Using existing copy of the cache.");
      [aLocalFolderCacheManager setPathToCache: thePath];
    }
  else
    {
      NSDebugLog(@"Creating new cache.");
      aLocalFolderCacheManager = [[LocalFolderCacheManager alloc] initWithPath: thePath];
      AUTORELEASE(aLocalFolderCacheManager);
    }
  
  return aLocalFolderCacheManager;
}


@end
