/*
	NSFileManager+directories.m
	Mon Dec  9 11:34:58 CET 2002
	stefan.boehringer@uni-essen.de

	
 */

#import	"NSFileManager+directories.h"
#include	<stdarg.h>

@implementation NSFileManager(NSFileManagerDirectories)

- (NSData *)dataRepresentationAtPath:(NSString *)somePath
{
	NSArray				*files = [self directoryContentsAtPath:somePath];
	NSMutableDictionary	*contentRep = [NSMutableDictionary dictionary];
	NSDictionary	*attributes;
	NSString	*filePath, *file;
	NSData		*contents;
	int	i, max;

	for (i = 0, max = [files count]; i < max; i++) {
		file = [files objectAtIndex:i];
		filePath = [somePath stringByAppendingPathComponent:file];
		attributes = [self fileAttributesAtPath:filePath traverseLink:YES];

		//	NSLog(@"%@", attributes);
		if (NSFileTypeDirectory == [attributes fileType]) {	// encountered a directory
			contents = [self dataRepresentationAtPath:filePath];
		} else {
			contents = [self contentsAtPath:filePath];
		}
		[contentRep setObject:[NSDictionary dictionaryWithObjectsAndKeys:
					attributes, @"attributes",
					contents, @"contents",
					nil
				]
			forKey:file
		];
	}
	return [NSArchiver archivedDataWithRootObject:contentRep];
}

//#define	ATTRIB_IS_DIR(a)	([a fileType] == NSFileTypeDirectory)
#define	ATTRIB_IS_DIR(a)	([[a fileType] isEqualToString:NSFileTypeDirectory])

- (void)writeDataRepresentation:(NSData *)data toPath:(NSString *)somePath
{
	NSDictionary	*directory = [NSUnarchiver unarchiveObjectWithData:data];
	NSEnumerator	*files = [directory keyEnumerator];
	NSString		*filePath, *file;
	NSDictionary	*attributes;
	NSData			*fileContents;

	for (; (file = [files nextObject]); ) {

		attributes = [[directory objectForKey:file] objectForKey:@"attributes"];
		filePath = [somePath stringByAppendingPathComponent:file];
		fileContents = [[directory objectForKey:file] objectForKey:@"contents"];

		if (ATTRIB_IS_DIR(attributes)) {	// encountered a directory
			[self createDirectoryAtPath:filePath attributes:attributes];
			[self writeDataRepresentation:fileContents toPath:filePath];
		} else {
			[self createFileAtPath:filePath contents:fileContents attributes:attributes];
		}
	}
}

- (BOOL)createAllDirectoriesComposingPath:(NSString *)path attributes:(NSDictionary *)attributes
{
	NSArray	*components = [path pathComponents];
	int		i, count;
	BOOL	isDir;

	for (i = 0, count = [components count]; i < count; i++) {
		NSString	*partialPath = [NSString pathWithComponents:
			[components subarrayWithRange:NSMakeRange(0, i + 1)]];
		if (![self fileExistsAtPath:partialPath isDirectory:&isDir]) {
			if (![self createDirectoryAtPath:partialPath attributes:attributes])
				return NO;
		} else {
			if (!isDir) [NSException raise:NSInvalidArgumentException
				format:@"path of directories is blocked by file [%@]", partialPath];
		}
	}
	return YES;
}

@end

@implementation NSFileManager(NSTemoraryFilesManagement)

- (NSString *)temporaryPathWithPrefix:(NSString *)prefix andPostfix:(NSString *)postfix
{
	NSString		*proposedPath;

	do {
		proposedPath = [NSString stringWithFormat:@"%@%lx%@",
			prefix, random(), postfix];
	} while ([self fileExistsAtPath:proposedPath]);

	return proposedPath;

}

- (NSString *)temporaryPathWithPrefix:(NSString *)prefix
{
	return [self temporaryPathWithPrefix:prefix andPostfix:nil];
}

- (NSString *)temporaryPathInTempPathWithPrefix:(NSString *)prefix andPostfix:(NSString *)postfix
{
	return [self temporaryPathWithPrefix:
			[NSTemporaryDirectory() stringByAppendingPathComponent:prefix]
		andPostfix:postfix
	];

}

- (NSString *)temporaryPathInTempPathWithPrefix:(NSString *)prefix
{
	return [self temporaryPathInTempPathWithPrefix:prefix andPostfix:nil];
}

@end

@implementation NSString(NSPathManipulationExtensions)

- (NSString *)stringByAppendingPathComponents:(NSString *)component1, ...
{
	NSString	*retV = self;
	NSString	*nextComponent = component1;
	va_list		components;

	va_start(components, component1);

	if (! component1) return self;
	do {
		retV = [retV stringByAppendingPathComponent:nextComponent];
	} while ( (nextComponent = va_arg(components, NSString *)) );

	va_end(components);
	return retV;
}

@end

#if 0

@implementation NSObject(DeallocBlock)
- (void)dealloc { /* fputs("didn't dealloc\n", stderr); */}
@end

#endif
