//
//  JaikuAPI.m
//  Afficheur
//
//  Created by kichi on 08/04/06.
//  Copyright 2008 Katsuhiko Ichinose. All rights reserved.
//

#import "JaikuAPI.h"
#import "NSStringOgreKit.h"
#import <OgreKit/OgreKit.h>
#import <openssl/hmac.h>

NSString *JaikuUser		= @"JaikuUser";
NSString *JaikuHost		= @"JaikuHost";
NSString *JaikuURL		= @"JaikuURL";
NSString *JaikuKey		= @"JaikuKey";
NSString *JaikuSecret	= @"JaikuSecret";

@implementation JaikuAPI

- (id)init
{
	self = [super init];
	if (self)
	{
		_keys = [[NSDictionary dictionaryWithObjectsAndKeys:
				  @"", JaikuUser,
				  @"", JaikuKey,
				  @"", JaikuSecret,
				  @"", JaikuHost,
				  @"", JaikuURL,
				  nil] retain];
		_dic = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
				@"", JaikuUser,
				@"", JaikuKey,
				@"", JaikuSecret,
				@"api.jaiku.com", JaikuHost,
				@"http://api.jaiku.com", JaikuURL,
				nil];
	}
	return self;
}

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

- (id)initWithDictionary:(NSDictionary *)dic
{
	self = [self init];
	if (self)
	{
		NSEnumerator *enumerator = [dic keyEnumerator];
		id key;
		while ((key = [enumerator nextObject])) {
			id val = [_keys valueForKey:key];
			if (val == nil)
			{
				EXPLOG(@"[%@ initWithDictionary] NoKey: %@", [self className], key);
			}
			else
			{
				id value = [dic valueForKey:key];
				[_dic setValue:value forKey:key];
				if ([key isEqualToString:JaikuKey])
				{
					[self setAccessToken:value];
				}
				else if ([key isEqualToString:JaikuSecret])
				{
					[self setAccessTokenSecret:value];
				}
			}
		}
	}
	return self;
}

- (NSString *)user
{
	return [_dic valueForKey:JaikuUser];
}

- (id)update:(NSString *)status
{
	return [self update:status withIcon:nil location:nil];
}

- (NSString *)encodeMessage:(NSString *)message
{
	return [HTTP urlEncode:message unescaped:nil escaped:@"&+=;"];
}

- (id)update:(NSString *)status
	withIcon:(NSString *)iconName
	location:(NSString *)location;
{
	LOG(@"[%@ update]\n%@\n%@", [self className], _access_token, _access_token_secret);
	NSString *aLocation = @"";
	if (location && ![location isEqualToString:@""])
	{
		aLocation = [NSString stringWithFormat:@"&location=%@",
					 [HTTP urlEncode:location
						   unescaped:nil
							 escaped:@"&+"]];
	}
	NSString *icon = @"";
	if (iconName && ![iconName isEqualToString:@""])
	{
		icon = [NSString stringWithFormat:@"&icon=%@", iconName];
	}
	NSString *nick = [NSString stringWithFormat:@"%@@jaiku.com", [_dic valueForKey:JaikuUser]];
	id result = [self postWithOAuth:[NSString stringWithFormat:@"%@/json",
									 [_dic valueForKey:JaikuURL]]
							 header:[NSMutableDictionary dictionaryWithObjectsAndKeys:
									 [_dic valueForKey:JaikuHost], @"Host",
									 @"application/x-www-form-urlencoded", @"Content-Type",
									 nil]
							   body:[NSString stringWithFormat:
									 @"method=post&message=%@%@%@&nick=%@",
									 [self encodeMessage:status],
									 icon,
									 aLocation,
									 [HTTP urlEncode:nick unescaped:nil escaped:@"/#"]]];
	return [self determineError:result WithJSON:YES];
}

- (id)comment:(NSString *)comment
	  withURL:(NSString *)url
{
	NSString *owner = @"";
	if ([url lengthOfRegularExpression:@"jaiku\\.com/channel/"])
	{
		owner = [url replaceWithExpression:@"^.*jaiku\\.com/channel/(.*?)/.*$" replace:@"#\\1@jaiku.com"];
	}
	else
	{
		owner = [url replaceWithExpression:@"^http://(.*?)\\.jaiku\\.com/.*$" replace:@"\\1@jaiku.com"];
	}
	NSString *uuid = [url replaceWithExpression:@"^.*/presence/(.*)$" replace:@"\\1"];
	NSString *nick = [NSString stringWithFormat:@"%@@jaiku.com", [_dic valueForKey:JaikuUser]];
	NSString *stream = [NSString stringWithFormat:@"stream/%@/presence", owner];
	NSString *entry = [NSString stringWithFormat:@"stream/%@/presence/%@", owner, uuid];
	//LOG(@"[%@ comment]\ncomment = %@\nstream = %@\nentry = %@\nuuid = %@\nnick = %@",
	//	[self className], comment, stream, entry, uuid, nick);
	id result = [self postWithOAuth:[NSString stringWithFormat:@"%@/json",
									 [_dic valueForKey:JaikuURL]]
							 header:[NSMutableDictionary dictionaryWithObjectsAndKeys:
									 [_dic valueForKey:JaikuHost], @"Host",
									 @"application/x-www-form-urlencoded", @"Content-Type",
									 nil]
							   body:[NSString stringWithFormat:
									 @"method=entry_add_comment&content=%@&stream=%@&entry=%@&nick=%@",
									 [self encodeMessage:comment],
									 [HTTP urlEncode:stream unescaped:nil escaped:@"@/#"],
									 [HTTP urlEncode:entry unescaped:nil escaped:@"@/#"],
									 [HTTP urlEncode:nick unescaped:nil escaped:@"@/#"]]];
	return [self determineError:result WithJSON:YES];
}

- (id)contactsFeed
{
	id result =[self getWithOAuth:[NSString stringWithFormat:
								   @"http://%@.jaiku.com/contacts/feed/json",
								   [_dic valueForKey:JaikuUser]
								   ]
						   header:[NSMutableDictionary dictionaryWithObjectsAndKeys:
								   [NSString stringWithFormat:@"%@.jaiku.com", [_dic valueForKey:JaikuUser]],
								   @"Host",
								   nil]
							 body:@""];
	return [self determineError:result WithJSON:YES];
}

- (id)headContactsFeed
{
#if 1
	id result =[self head:@"http://www.jaiku.com/"
				   header:[NSMutableDictionary dictionaryWithObjectsAndKeys:
						   @"www.jaiku.com", @"Host",
						   nil]
					 body:@""];
#else
	id result =[self headWithOAuth:[NSString stringWithFormat:
									@"http://%@.jaiku.com/contacts/feed/json",
									[_dic valueForKey:JaikuUser]
									]
							header:[NSMutableDictionary dictionaryWithObjectsAndKeys:
									[NSString stringWithFormat:@"%@.jaiku.com", [_dic valueForKey:JaikuUser]],
									@"Host",
									nil]
							  body:@""];
#endif
	return result;	//[self determineError:result WithJSON:YES];
}

- (id)userInfo:(NSString *)user
{
	if (!user)
	{
		user = [_dic valueForKey:JaikuUser];
	}
	id result =[self getWithOAuth:[NSString stringWithFormat:
								   @"http://%@.jaiku.com/json",
								   user
								   ]
						   header:[NSMutableDictionary dictionaryWithObjectsAndKeys:
								   [NSString stringWithFormat:@"%@.jaiku.com", user],
								   @"Host",
								   nil]
							 body:@""];
	return [self determineError:result WithJSON:YES];
}

@end
