/*
   Project: UL

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   Created: 2005-07-12 15:24:33 +0200 by michael johnston

   This application is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This application 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
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/

#include "ULFramework/ULDatabaseSimulationIndex.h"

@implementation ULDatabaseSimulationIndex

- (void) addObject: (id) object
{
	int retVal;
	NSString* ident;
	NSString* storagePath, *destinationPath, *linkPath;

	//add the ULSimulation as normal
	[super addObject: object];
	ident = [object identification];

	//check where the simulation data storage is - if its not in the
	//simulation directory copy it there 

	storagePath = [[object dataStorage] storagePath];
	if(![[storagePath stringByDeletingLastPathComponent] isEqual:
		databaseDir])
	{
		destinationPath =  [databaseDir stringByAppendingPathComponent: 
					[NSString stringWithFormat: @"%@_Data", ident]];

		retVal = [[NSFileManager defaultManager]
				copyPath: storagePath
				toPath: destinationPath
				handler: nil];
		if(retVal)
		{
			storagePath = destinationPath;
			linkPath = [databaseDir stringByAppendingPathComponent:
					[NSString stringWithFormat: @"%@.output", [object name]]];

			if(![[NSFileManager defaultManager] createSymbolicLinkAtPath: linkPath
				pathContent: storagePath])
			{
				NSWarnLog(@"Failed to create link when moving simulation storage");
				linkPath = @"None";
			}

			[object setValue: linkPath forMetadataKey: @"DataLink"];
		}
		else
		{
			NSWarnLog(@"Unable to copy downloaded data into file system database");
		}
	}
	
	//FIXME: What to do if we cant move the storage directory ??
	//Do we add the current (probably temporary) location or something else?
	
	//Add the location of the simulation data directory to the index metadata
	[[index objectForKey: ident] setObject: storagePath
		forKey: @"SimulationDataPath"];
	//FIXME: Temporary?? 
	//add the name of link used to easily id the data directory
	[[index objectForKey: ident] setObject: [object valueForMetadataKey: @"DataLink"] 
		forKey: @"DataLink"];

	[indexArray release];
	indexArray = [[index allValues] retain];
}

- (void) removeObjectWithId: (id) ident
{
	BOOL retVal;
	NSString* filePath, *link;
	NSFileManager* fileManager;
	id object;

	//first remove the simulation data

	object = [index objectForKey: ident];
	if(object != nil)
	{
		filePath = [object objectForKey: @"SimulationDataPath"];
		if(filePath == nil)
		{
			NSWarnLog(@"No path given for simulation data of object %@."
				, ident);
			NSWarnLog(@"It will not be removed if it exists.");
		}
		else
		{	
			fileManager = [NSFileManager defaultManager];	
		
			NSDebugLLog(@"ULDatabaseSimulationIndex",
				@"Removing data directory at %@", 
					filePath);

			if([fileManager fileExistsAtPath: filePath])
			{
				if([fileManager isDeletableFileAtPath: filePath])
				{
					[fileManager removeFileAtPath: filePath
						handler: nil];
				}
				else
				{
					NSWarnLog(@"Failed to remove data directory");
					[NSException raise: NSInternalInconsistencyException
						format: [NSString stringWithFormat: 
							@"Unable to remove data directory %@ from database", 
							filePath]];
				}
			}	
			else
				NSWarnLog(@"Data %@ not present at expected path %@", filePath);
			
			//Remove the link to the data directory 
			//(if its still valid)

			link = [object objectForKey: @"DataLink"];
			if(link == nil)
			{
				NSWarnLog(@"No link present to directory %@", filePath);
			}	
			else
			{
				if([filePath isEqual:
					[fileManager pathContentOfSymbolicLinkAtPath: link]])
				{
					retVal = [fileManager removeFileAtPath:	link handler: nil];
					if(!retVal)
						NSWarnLog(@"Unable to remove link %@", link);
				}
				else
				{
					NSWarnLog(@"%@ is not a valid link to directory %@", 
						link,
						filePath);
				}		
			}


		}	

	}

	//Remove the simulation object
	[super removeObjectWithId: ident];
}

- (id) unarchiveObjectWithId: (NSString*) ident
{
	id object, dataStorage;
	NSString* storagePath; 

	//unarchive the object as normal
	object = [super unarchiveObjectWithId: ident];
	
	//create a dataStorage object so the object can
	//access its data. We saved the path under the
	//key "SimulationDataPath" in the index.

	storagePath = [[index objectForKey: ident]
			objectForKey: @"SimulationDataPath"];
	NSDebugMLLog(@"ULDatabaseIndex", @"Storage path is %@", storagePath);		
	dataStorage = [[ULFileSystemSimulationStorage alloc]
			initForReadingSimulationDataAtPath: storagePath];
	[dataStorage autorelease];
	[object setDataStorage: dataStorage];

	return object;
}

- (void) updateMetadataForObject: (id) object
{
	id storagePath;
	NSString* ident;

	[super updateMetadataForObject: object];

	ident = [object identification];
	storagePath = [[object dataStorage] storagePath];
	//FIXME: See addObject for problem with next two lines.
	[[index objectForKey: ident] setObject: storagePath
		forKey: @"SimulationDataPath"];
	[[index objectForKey: ident] setObject: [object valueForMetadataKey: @"DataLink"] 
		forKey: @"DataLink"];
}

@end
