#import <Foundation/Foundation.h>
#import <time.h>

/* User Defaults:
 *
 * Threads <int> - number of threads to create
 * Requests <int> - number of requests per thread
 * URL <string> - URL to download
 */
@interface TestDriver : NSObject
{
	int done;
	int failed;
	NSLock *lock;
}
- (int)testRun;
- (void)threadFinished: (NSNotification *)n;
- (void)testPerformer: (id)tests;
@end

int main (int argc, const char * argv[])
{
	int returnValue;
	TestDriver *driver;
	NSUserDefaults *defs;
	
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	defs = [NSUserDefaults standardUserDefaults];
	driver = [[[TestDriver alloc] init] autorelease];
	[[NSNotificationCenter defaultCenter] addObserver: driver
			selector: @selector(threadFinished:) name: NSThreadWillExitNotification object: nil];
	returnValue = [driver testRun];
	//run the run loop - we quit when all threads have exited
	[[NSRunLoop currentRunLoop] run];

    [pool release];
    return returnValue;
}

@implementation TestDriver

+ (void)initialize
{
	NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
	NSMutableDictionary *dict = [NSMutableDictionary dictionary];
	
	[dict setObject: [NSNumber numberWithInt: 100]    forKey: @"Requests"];
	[dict setObject: [NSNumber numberWithInt: 10]     forKey: @"Threads"];
	[dict setObject: @"http://www.gnustep.org/"       forKey: @"URL"];
	
	[defs registerDefaults: dict];
}

- (int)testRun
{
	NSUserDefaults *defs;
	NSNumber *reqs;
	int i, threads, requests, count;
	
	done = failed = 0;
	lock = [[NSLock alloc] init];
	
	defs = [NSUserDefaults standardUserDefaults];
	threads = [defs integerForKey: @"Threads"];
	requests = [defs integerForKey: @"Requests"];
	count = threads * requests;
	reqs = [NSNumber numberWithInt: requests];

	NSLog(@"Initialising...");
	for (i = 0; i < threads; i++)
	{
		[NSThread detachNewThreadSelector: @selector(testPerformer:) toTarget:self
			withObject: reqs];
	}

	NSLog(@"All tests launched");
	return 0;
}

- (void)testPerformer: (id)tests
{
	int i, requests;
	NSURL *url;
	NSURLHandle *urlHandle;
	NSString *urlAsString;
	NSData *retrieved;
	NSAutoreleasePool *localPool;
	
	localPool = [[NSAutoreleasePool alloc] init];
	requests = [tests intValue];
	urlAsString = [[NSUserDefaults standardUserDefaults] stringForKey: @"URL"];
	url = [NSURL URLWithString: urlAsString];
	
	for (i = 0; i < requests; i++)
	{
		//make initial request
		urlHandle = [[[NSURLHandle URLHandleClassForURL: url] alloc] initWithURL: url cached:NO];
		retrieved = [urlHandle loadInForeground];
		
		if ((nil == retrieved) || (0 == [retrieved length]))
		{
			[lock lock];
			failed++;
			[lock unlock];
			goto bail;
		}
	  bail:
		[urlHandle release];
	}
	[localPool release];
	return;
}

- (void)threadFinished: (NSNotification *)n
{
	int threads = [[NSUserDefaults standardUserDefaults] integerForKey: @"Threads"];
	if (++done == threads)
	{
		int count = threads * [[NSUserDefaults standardUserDefaults] integerForKey: @"Requests"];
		NSLog(@"%d requests completed, %d of which failed", count, failed);
		exit(EXIT_SUCCESS);
	}
}

- (void)dealloc
{
	[lock release];
	[super dealloc];
}

@end