//
//  SFSProtocolCodec.m
//  SFS2X
//
//  Original development by Infosfer Game Technologies Ltd. | http://www.infosfer.com.
//
//  Maintained and developed by A51 Integrated.
//  Copyright 2012 A51 Integrated | http://a51integrated.com. All rights reserved.
//

#import "SFSProtocolCodec.h"
#import "SFSCodecException.h"
#import "SFSException.h"
#import "ISFSObject.h"
#import "SFSObject.h"
#import "IController.h"
#import "BitSwarmClient.h"
#import "Logger.h"
#import "Message.h"

@implementation SFSProtocolCodec

static NSString * SFSProtocolCodec_CONTROLLER_ID = @"c";
static NSString * SFSProtocolCodec_ACTION_ID = @"a";
static NSString * SFSProtocolCodec_PARAM_ID = @"p";
static NSString * SFSProtocolCodec_UDP = @"d";
static NSString * SFSProtocolCodec_USER_ID = @"u";
static NSString * SFSProtocolCodec_UDP_PACKET_ID = @"i";

@synthesize log = _log;
@synthesize bitSwarm = _bitSwarm;
@dynamic ioHandler;

-(id)initWithIoHandler:(id <IoHandler>)ioHandler bitSwarm:(BitSwarmClient *)bitSwarm {
	if ((self = [super init])) {
		self.ioHandler = ioHandler;
		self.log = [Logger getInstance];
		self.bitSwarm = bitSwarm;
	}
	return self;
}


-(void)dispatchRequest:(id <ISFSObject>)requestObject{
	
	id <IMessage> message = [[Message alloc] init];
	
	if ([requestObject isNull:SFSProtocolCodec_CONTROLLER_ID]) {
		@throw [SFSCodecException exceptionWithReason:@"Request rejected: No Controller ID in request!"];
	}
	if ([requestObject isNull:SFSProtocolCodec_ACTION_ID]) {
		@throw [SFSCodecException exceptionWithReason:@"Request rejected: No Action ID in request!"];
	}
	
	[message setId:[requestObject getByte:SFSProtocolCodec_ACTION_ID]];
	[message setContent:[requestObject getSFSObject:SFSProtocolCodec_PARAM_ID]];
    [message setIsUDP:[requestObject getBool:SFSProtocolCodec_UDP]];
	
	int controllerId = (int)[requestObject getByte:SFSProtocolCodec_CONTROLLER_ID];
	id <IController> controller = [_bitSwarm getController:controllerId];
	
	if (controller == nil) {
		@throw [SFSException exceptionWithReason:[NSString stringWithFormat:@"Cannot handle server response. Unknown controller, id: %d", controllerId]];
	}
	[controller handleMessage:message];
}


-(id <IoHandler>)ioHandler
{
	return _ioHandler;
}

-(void)setIoHandler:(id <IoHandler>)handler
{
	
	if (_ioHandler != nil)
    {
		@throw [SFSException exceptionWithReason:[NSString stringWithFormat:@"IOHandler is already defined for this ProtocolHandler instance: %@", NSStringFromClass([self class])]];
	}
	else
    {
		_ioHandler = handler;
	}
}
-(void)onPacketRead:(NSData *)packet
{
	id <ISFSObject> sfsObj = [SFSObject newFromBinaryData:packet];
	
	[self dispatchRequest:sfsObj];
}


-(void)onPacketWrite:(id <IMessage>)message
{
	
	id <ISFSObject> sfsObj = [SFSObject newInstance];
    [sfsObj putByte:SFSProtocolCodec_CONTROLLER_ID value:[message targetController]];
    
    if([message isUDP])
    {
        //Fixed bug where 0 was seen as false; Users can have an id of 0;
        int uid = ([_bitSwarm mySelfId] > -1) ? [_bitSwarm mySelfId] : -1;
        
        [sfsObj putInt:SFSProtocolCodec_USER_ID value: uid];
        [sfsObj putLong:SFSProtocolCodec_UDP_PACKET_ID value: [_bitSwarm nextUdpPacketId]];
    }
    else
    {
        [sfsObj putShort:SFSProtocolCodec_ACTION_ID value:[message id]];
    }
	
	[sfsObj putSFSObject:SFSProtocolCodec_PARAM_ID value:[message content]];
	[message setContent:sfsObj];
    
	[_ioHandler onDataWrite:message];

}


@end
