//
//  main.m
//  DefaultDistributionLinker
//
//  Created by coder on 04/12/06.
//  Copyright Laurens'Tribune 2006. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <sys/sysctl.h>
#import <mach/machine.h>

int main(int argc, char *argv[])
{
	NSAutoreleasePool * POOL = [[NSAutoreleasePool alloc] init];
	NSProcessInfo * PI = [NSProcessInfo processInfo];
	NSArray * arguments = [PI arguments];
	NSFileManager * DFM = [NSFileManager defaultManager];
//NSLog(@"[DFM currentDirectoryPath] %@",[DFM currentDirectoryPath]);
	NSEnumerator * E = [arguments objectEnumerator];
	NSString * argument = nil;
	NSString * source = nil;
	NSString * destination = nil;
	while(argument = [E nextObject])
	{
		if([argument isEqual:@"--source"])
		{
			source = [E nextObject];
		}
		else if([argument isEqual:@"--destination"])
		{
			destination = [E nextObject];
		}
	}
	if(![source length])
	{
		NSLog(@"No source given");
		[POOL release];
		return 8;
	}
	if(![destination length])
	{
		NSLog(@"No destination given");
		[POOL release];
		return 7;
	}
	NSLog(@"ln -s \"%@\" \"%@\"",destination,source);
	// ln -s destination source
	// source is expected to be a directory
	BOOL isDirectory = NO;
	if([DFM fileExistsAtPath:source isDirectory:&isDirectory])
	{
		if(!isDirectory)
		{
			NSLog(@"A directory was expected at:%@",source);
			[POOL release];
			return 6;
		}
	}
	else if(![DFM createDirectoryAtPath:source attributes:nil])
	{
		NSLog(@"Could not create a directory at:%@",source);
		[POOL release];
		return 5;
	}
	NSString * coreDestination = [destination lastPathComponent];
	source = [source stringByAppendingPathComponent:coreDestination];
	NSString * safeSource = [source stringByAppendingPathExtension:@"safe"];
//NSLog(@"dirName %@",dirName);
//NSLog(@"source %@",source);
//NSLog(@"safeSource %@",safeSource);
//NSLog(@"destination %@",destination);
//NSLog(@"%@ directory: %@",DFM,[DFM directoryContentsAtPath:dirName]);
	if([DFM fileExistsAtPath:safeSource] || [DFM pathContentOfSymbolicLinkAtPath:safeSource])
	{
		if([DFM removeFileAtPath:safeSource handler:NULL])
		{
			NSLog(@"File successfully removed at %@",safeSource);
		}
		else
		{
			NSLog(@"****  TeXDist ERROR: Could not remove %@!",safeSource);
			[POOL release];
			return 1;
		}
	}
	else
	{
		NSLog(@"No file at %@",safeSource);
	}
//NSLog(@"01-directory %@",[DFM directoryContentsAtPath:dirName]);
	if(![DFM createSymbolicLinkAtPath:safeSource pathContent:destination])
	{
		NSLog(@"****  TeXDist ERROR: Could not link %@ to %@!",safeSource,destination);
		[POOL release];
		return 2;
	}
//NSLog(@"2-directory %@",[DFM directoryContentsAtPath:dirName]);
	if([DFM fileExistsAtPath:source] || [DFM pathContentOfSymbolicLinkAtPath:source])
	{
		if(![DFM removeFileAtPath:source handler:NULL])
		{
			NSLog(@"****  TeXDist ERROR: Could not remove %@!",safeSource);
			[POOL release];
			return 3;
		}
//NSLog(@"3-directory %@",[DFM directoryContentsAtPath:dirName]);
	}
	if(![DFM movePath:safeSource toPath:source handler:NULL])
	{
		NSLog(@"****  TeXDist ERROR: Could not move %@ to %@!",safeSource,source);
		[POOL release];
		return 4;
	}
//NSLog(@"4-directory %@",[DFM directoryContentsAtPath:dirName]);
	// Does /usr/texbin still point to ../Library/TeX/Distributions/.DefaultTeX/Contents/Programs/i386
	NSString * usr = [NSOpenStepRootDirectory() stringByAppendingPathComponent:@"usr"];
	NSString * texbin = [usr stringByAppendingPathComponent:@"texbin"];
	NSString * texpath = [texbin stringByAppendingPathComponent:@"tex"];
	texpath = [texpath stringByResolvingSymlinksInPath];
	NSArray * Libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSLocalDomainMask,YES);
	NSString * Library = [Libraries lastObject];
	NSString * expectedDestination = [Library stringByAppendingPathComponent:
		@"TeX/Distributions/.DefaultTeX/Contents/Programs"];
	int cpu_type;
	size_t length = sizeof(cpu_type);
	sysctlbyname("hw.cputype", &cpu_type, &length, NULL, 0);
	expectedDestination = [expectedDestination stringByAppendingPathComponent:
		(cpu_type == CPU_TYPE_I386?@"i386":@"powerpc")];
	NSString * storedDesination = [@".." stringByAppendingPathComponent:expectedDestination];
	// What is the link destination?
	if(![DFM fileExistsAtPath:texbin isDirectory:&isDirectory])
	{
create:
		if(![DFM createSymbolicLinkAtPath:texbin pathContent:storedDesination])
		{
			NSLog(@"****  TeXDist ERROR: Could not link %@ to %@!",texbin,storedDesination);
			[POOL release];
			return 14;
		}
	}
	else if(!isDirectory)
	{
		NSLog(@"Unexpected file at %@",texbin);
remove:
		if(![DFM removeFileAtPath:texbin handler:NULL])
		{
			NSLog(@"****  TeXDist ERROR: Could not remove %@!",texbin);
			[POOL release];
			return 13;
		}
		goto create;
	}
	if(![DFM isExecutableFileAtPath:texpath])
	{
		NSLog(@"****  TeXDist ERROR: no executable at %@!",texpath);
		// trying to recover
		char * buf = (char *)NSZoneMalloc(NSDefaultMallocZone(),PATH_MAX+1);
		if(!buf)
		{
			NSLog(@"Memory management error (2)");
			[POOL release];
			return 12;
		}
		ssize_t size = readlink([texbin fileSystemRepresentation],buf,PATH_MAX);
		if(size<0)
		{
			NSLog(@"Error reading the contents of the link");
			[POOL release];
			return 11;
		}
		buf[size]='\0';
		NSString * readLink = [NSString stringWithUTF8String:buf];
		NSZoneFree(NSDefaultMallocZone(),buf);
		buf = nil;
		NSString * destination = [usr stringByAppendingPathComponent:readLink];
		destination = [destination stringByStandardizingPath];
		if([destination isEqual:expectedDestination])
		{
			NSLog(@"I don't know what's wrong, missing a /usr/texbin/tex, it it normal?");
			[POOL release];
			return 9;
		}
		goto remove;
	}
	[POOL release];
	return 0;
}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=  NSView(TeXDist_Validate)
