/*
uSynergy client -- Implementation for the embedded Synergy client library
  version 1.0.0, July 7th, 2012

Copyright (c) 2012 Alex Evans

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

   1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.

   2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

   3. This notice may not be removed or altered from any source
   distribution.
*/
#include "uSynergy.h"
#include <stdio.h>
#include <string.h>



//---------------------------------------------------------------------------------------------------------------------
//	Internal helpers
//---------------------------------------------------------------------------------------------------------------------



/**
@brief Read 16 bit integer in network byte order and convert to native byte order
**/
static int16_t sNetToNative16(const unsigned char *value)
{
#ifdef USYNERGY_LITTLE_ENDIAN
	return value[1] | (value[0] << 8);
#else
	return value[0] | (value[1] << 8);
#endif
}



/**
@brief Read 32 bit integer in network byte order and convert to native byte order
**/
static int32_t sNetToNative32(const unsigned char *value)
{
#ifdef USYNERGY_LITTLE_ENDIAN
	return value[3] | (value[2] << 8) | (value[1] << 16) | (value[0] << 24);
#else
	return value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
#endif
}



/**
@brief Trace text to client
**/
static void sTrace(uSynergyContext *context, const char* text)
{
	// Don't trace if we don't have a trace function
	if (context->m_traceFunc != 0L)
		context->m_traceFunc(context->m_cookie, text);
}



/**
@brief Add string to reply packet
**/
static void sAddString(uSynergyContext *context, const char *string)
{
	size_t len = strlen(string);
	memcpy(context->m_replyCur, string, len);
	context->m_replyCur += len;
}



/**
@brief Add uint8 to reply packet
**/
static void sAddUInt8(uSynergyContext *context, uint8_t value)
{
	*context->m_replyCur++ = value;
}



/**
@brief Add uint16 to reply packet
**/
static void sAddUInt16(uSynergyContext *context, uint16_t value)
{
	uint8_t *reply = context->m_replyCur;
	*reply++ = (uint8_t)(value >> 8);
	*reply++ = (uint8_t)value;
	context->m_replyCur = reply;
}



/**
@brief Add uint32 to reply packet
**/
static void sAddUInt32(uSynergyContext *context, uint32_t value)
{
	uint8_t *reply = context->m_replyCur;
	*reply++ = (uint8_t)(value >> 24);
	*reply++ = (uint8_t)(value >> 16);
	*reply++ = (uint8_t)(value >> 8);
	*reply++ = (uint8_t)value;
	context->m_replyCur = reply;
}



/**
@brief Send reply packet
**/
static uSynergyBool sSendReply(uSynergyContext *context)
{
	// Set header size
	uint8_t		*reply_buf	= context->m_replyBuffer;
	uint32_t	reply_len	= (uint32_t)(context->m_replyCur - reply_buf);				/* Total size of reply */
	uint32_t	body_len	= reply_len - 4;											/* Size of body */
	uSynergyBool ret;
	reply_buf[0] = (uint8_t)(body_len >> 24);
	reply_buf[1] = (uint8_t)(body_len >> 16);
	reply_buf[2] = (uint8_t)(body_len >> 8);
	reply_buf[3] = (uint8_t)body_len;

	// Send reply
	ret = context->m_sendFunc(context->m_cookie, context->m_replyBuffer, reply_len);

	// Reset reply buffer write pointer
	context->m_replyCur = context->m_replyBuffer+4;
	return ret;
}



/**
@brief Call mouse callback after a mouse event
**/
static void sSendMouseCallback(uSynergyContext *context)
{
	// Skip if no callback is installed
	if (context->m_mouseCallback == 0L)
		return;

	// Send callback
	context->m_mouseCallback(context->m_cookie, context->m_mouseX, context->m_mouseY, context->m_mouseWheelX,
		context->m_mouseWheelY, context->m_mouseButtonLeft, context->m_mouseButtonRight, context->m_mouseButtonMiddle);
}



/**
@brief Send keyboard callback when a key has been pressed or released
**/
static void sSendKeyboardCallback(uSynergyContext *context, uint16_t key, uint16_t modifiers, uSynergyBool down, uSynergyBool repeat)
{
	// Skip if no callback is installed
	if (context->m_keyboardCallback == 0L)
		return;

	// Send callback
	context->m_keyboardCallback(context->m_cookie, key, modifiers, down, repeat);
}



/**
@brief Send joystick callback
**/
static void sSendJoystickCallback(uSynergyContext *context, uint8_t joyNum)
{
	int8_t *sticks;

	// Skip if no callback is installed
	if (context->m_joystickCallback == 0L)
		return;

	// Send callback
	sticks = context->m_joystickSticks[joyNum];
	context->m_joystickCallback(context->m_cookie, joyNum, context->m_joystickButtons[joyNum], sticks[0], sticks[1], sticks[2], sticks[3]);
}



/**
@brief Parse a single client message, update state, send callbacks and send replies
**/
#define USYNERGY_IS_PACKET(pkt_id)	memcmp(message+4, pkt_id, 4)==0
static void sProcessMessage(uSynergyContext *context, const uint8_t *message)
{
	// We have a packet!
	if (memcmp(message+4, "Synergy", 7)==0)
	{
		// Welcome message
		//		kMsgHello			= "Synergy%2i%2i"
		//		kMsgHelloBack		= "Synergy%2i%2i%s"
		sAddString(context, "Synergy");
		sAddUInt16(context, USYNERGY_PROTOCOL_MAJOR);
		sAddUInt16(context, USYNERGY_PROTOCOL_MINOR);
		sAddUInt32(context, (uint32_t)strlen(context->m_clientName));
		sAddString(context, context->m_clientName);
		if (!sSendReply(context))
		{
			// Send reply failed, let's try to reconnect
			sTrace(context, "SendReply failed, trying to reconnect in a second");
			context->m_connected = USYNERGY_FALSE;
			context->m_sleepFunc(context->m_cookie, 1000);
		}
		else
		{
			// Let's assume we're connected
			char buffer[256+1];
			sprintf(buffer, "Connected as client \"%s\"", context->m_clientName);
			sTrace(context, buffer);
			context->m_hasReceivedHello = USYNERGY_TRUE;
		}
		return;
	}
	else if (USYNERGY_IS_PACKET("QINF"))
	{
		// Screen info. Reply with DINF
		//		kMsgQInfo			= "QINF"
		//		kMsgDInfo			= "DINF%2i%2i%2i%2i%2i%2i%2i"
		uint16_t x = 0, y = 0, warp = 0;
		sAddString(context, "DINF");
		sAddUInt16(context, x);
		sAddUInt16(context, y);
		sAddUInt16(context, context->m_clientWidth);
		sAddUInt16(context, context->m_clientHeight);
		sAddUInt16(context, warp);
		sAddUInt16(context, 0);		// mx?
		sAddUInt16(context, 0);		// my?
		sSendReply(context);
		return;
	}
	else if (USYNERGY_IS_PACKET("CIAK"))
	{
		// Do nothing?
		//		kMsgCInfoAck		= "CIAK"
		return;
	}
	else if (USYNERGY_IS_PACKET("CROP"))
	{
		// Do nothing?
		//		kMsgCResetOptions	= "CROP"
		return;
	}
	else if (USYNERGY_IS_PACKET("CINN"))
	{
		// Screen enter. Reply with CNOP
		//		kMsgCEnter 			= "CINN%2i%2i%4i%2i"

		// Obtain the Synergy sequence number
		context->m_sequenceNumber = sNetToNative32(message + 12);
		context->m_isCaptured = USYNERGY_TRUE;

		// Call callback
		if (context->m_screenActiveCallback != 0L)
			context->m_screenActiveCallback(context->m_cookie, USYNERGY_TRUE);
	}
	else if (USYNERGY_IS_PACKET("COUT"))
	{
		// Screen leave
		//		kMsgCLeave 			= "COUT"
		context->m_isCaptured = USYNERGY_FALSE;

		// Call callback
		if (context->m_screenActiveCallback != 0L)
			context->m_screenActiveCallback(context->m_cookie, USYNERGY_FALSE);
	}
	else if (USYNERGY_IS_PACKET("DMDN"))
	{
		// Mouse down
		//		kMsgDMouseDown		= "DMDN%1i"
		char btn = message[8]-1;
		if (btn==2)
			context->m_mouseButtonRight		= USYNERGY_TRUE;
		else if (btn==1)
			context->m_mouseButtonMiddle	= USYNERGY_TRUE;
		else
			context->m_mouseButtonLeft		= USYNERGY_TRUE;
		sSendMouseCallback(context);
	}
	else if (USYNERGY_IS_PACKET("DMUP"))
	{
		// Mouse up
		//		kMsgDMouseUp		= "DMUP%1i"
		char btn = message[8]-1;
		if (btn==2)
			context->m_mouseButtonRight		= USYNERGY_FALSE;
		else if (btn==1)
			context->m_mouseButtonMiddle	= USYNERGY_FALSE;
		else
			context->m_mouseButtonLeft		= USYNERGY_FALSE;
		sSendMouseCallback(context);
	}
	else if (USYNERGY_IS_PACKET("DMMV"))
	{
		// Mouse move. Reply with CNOP
		//		kMsgDMouseMove		= "DMMV%2i%2i"
		context->m_mouseX = sNetToNative16(message+8);
		context->m_mouseY = sNetToNative16(message+10);
		sSendMouseCallback(context);
	}
	else if (USYNERGY_IS_PACKET("DMWM"))
	{
		// Mouse wheel
		//		kMsgDMouseWheel		= "DMWM%2i%2i"
		//		kMsgDMouseWheel1_0	= "DMWM%2i"
		context->m_mouseWheelX += sNetToNative16(message+8);
		context->m_mouseWheelY += sNetToNative16(message+10);
		sSendMouseCallback(context);
	}
	else if (USYNERGY_IS_PACKET("DKDN"))
	{
		// Key down
		//		kMsgDKeyDown		= "DKDN%2i%2i%2i"
		//		kMsgDKeyDown1_0		= "DKDN%2i%2i"
		//uint16_t id = sNetToNative16(message+8);
		uint16_t mod = sNetToNative16(message+10);
		uint16_t key = sNetToNative16(message+12);
		sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, USYNERGY_FALSE);
	}
	else if (USYNERGY_IS_PACKET("DKRP"))
	{
		// Key repeat
		//		kMsgDKeyRepeat		= "DKRP%2i%2i%2i%2i"
		//		kMsgDKeyRepeat1_0	= "DKRP%2i%2i%2i"
		uint16_t mod = sNetToNative16(message+10);
//		uint16_t count = sNetToNative16(message+12);
		uint16_t key = sNetToNative16(message+14);
		sSendKeyboardCallback(context, key, mod, USYNERGY_TRUE, USYNERGY_TRUE);
	}
	else if (USYNERGY_IS_PACKET("DKUP"))
	{
		// Key up
		//		kMsgDKeyUp			= "DKUP%2i%2i%2i"
		//		kMsgDKeyUp1_0		= "DKUP%2i%2i"
		//uint16 id=Endian::sNetToNative(sbuf[4]);
		uint16_t mod = sNetToNative16(message+10);
		uint16_t key = sNetToNative16(message+12);
		sSendKeyboardCallback(context, key, mod, USYNERGY_FALSE, USYNERGY_FALSE);
	}
	else if (USYNERGY_IS_PACKET("DGBT"))
	{
		// Joystick buttons
		//		kMsgDGameButtons	= "DGBT%1i%2i";
		uint8_t	joy_num = message[8];
		if (joy_num<USYNERGY_NUM_JOYSTICKS)
		{
			// Copy button state, then send callback
			context->m_joystickButtons[joy_num] = (message[9] << 8) | message[10];
			sSendJoystickCallback(context, joy_num);
		}
	}
	else if (USYNERGY_IS_PACKET("DGST"))
	{
		// Joystick sticks
		//		kMsgDGameSticks		= "DGST%1i%1i%1i%1i%1i";
		uint8_t	joy_num = message[8];
		if (joy_num<USYNERGY_NUM_JOYSTICKS)
		{
			// Copy stick state, then send callback
			memcpy(context->m_joystickSticks[joy_num], message+9, 4);
			sSendJoystickCallback(context, joy_num);
		}
	}
	else if (USYNERGY_IS_PACKET("DSOP"))
	{
		// Set options
		//		kMsgDSetOptions		= "DSOP%4I"
	}
	else if (USYNERGY_IS_PACKET("CALV"))
	{
		// Keepalive, reply with CALV and then CNOP
		//		kMsgCKeepAlive		= "CALV"
		sAddString(context, "CALV");
		sSendReply(context);
		// now reply with CNOP
	}
	else if (USYNERGY_IS_PACKET("DCLP"))
	{
		// Clipboard message
		//		kMsgDClipboard		= "DCLP%1i%4i%s"
		//
		// The clipboard message contains:
		//		1 uint32:	The size of the message
		//		4 chars: 	The identifier ("DCLP")
		//		1 uint8: 	The clipboard index
		//		1 uint32:	The sequence number. It's zero, because this message is always coming from the server?
		//		1 uint32:	The total size of the remaining 'string' (as per the Synergy %s string format (which is 1 uint32 for size followed by a char buffer (not necessarily null terminated)).
		//		1 uint32:	The number of formats present in the message
		// And then 'number of formats' times the following:
		//		1 uint32:	The format of the clipboard data
		//		1 uint32:	The size n of the clipboard data
		//		n uint8:	The clipboard data
		const uint8_t *	parse_msg	= message+17;
		uint32_t		num_formats = sNetToNative32(parse_msg);
		parse_msg += 4;
		for (; num_formats; num_formats--)
		{
			// Parse clipboard format header
			uint32_t format	= sNetToNative32(parse_msg);
			uint32_t size	= sNetToNative32(parse_msg+4);
			parse_msg += 8;
			
			// Call callback
			if (context->m_clipboardCallback)
				context->m_clipboardCallback(context->m_cookie, format, parse_msg, size);

			parse_msg += size;
		}
	}
	else
	{
		// Unknown packet, could be any of these
		//		kMsgCNoop 			= "CNOP"
		//		kMsgCClose 			= "CBYE"
		//		kMsgCClipboard 		= "CCLP%1i%4i"
		//		kMsgCScreenSaver 	= "CSEC%1i"
		//		kMsgDKeyRepeat		= "DKRP%2i%2i%2i%2i"
		//		kMsgDKeyRepeat1_0	= "DKRP%2i%2i%2i"
		//		kMsgDMouseRelMove	= "DMRM%2i%2i"
		//		kMsgEIncompatible	= "EICV%2i%2i"
		//		kMsgEBusy 			= "EBSY"
		//		kMsgEUnknown		= "EUNK"
		//		kMsgEBad			= "EBAD"
		char buffer[64];
		sprintf(buffer, "Unknown packet '%c%c%c%c'", message[4], message[5], message[6], message[7]);
		sTrace(context, buffer);
		return;
	}

	// Reply with CNOP maybe?
	sAddString(context, "CNOP");
	sSendReply(context);
}
#undef USYNERGY_IS_PACKET



/**
@brief Mark context as being disconnected
**/
static void sSetDisconnected(uSynergyContext *context)
{
	context->m_connected		= USYNERGY_FALSE;
	context->m_hasReceivedHello = USYNERGY_FALSE;
	context->m_isCaptured		= USYNERGY_FALSE;
	context->m_replyCur			= context->m_replyBuffer + 4;
	context->m_sequenceNumber	= 0;
}



/**
@brief Update a connected context
**/
static void sUpdateContext(uSynergyContext *context)
{
	/* Receive data (blocking) */
	int receive_size = USYNERGY_RECEIVE_BUFFER_SIZE - context->m_receiveOfs;
	int num_received = 0;
	int packlen = 0;
	if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer + context->m_receiveOfs, receive_size, &num_received) == USYNERGY_FALSE)
	{
		/* Receive failed, let's try to reconnect */
		char buffer[128];
		sprintf(buffer, "Receive failed (%d bytes asked, %d bytes received), trying to reconnect in a second", receive_size, num_received);
		sTrace(context, buffer);
		sSetDisconnected(context);
		context->m_sleepFunc(context->m_cookie, 1000);
		return;
	}
	context->m_receiveOfs += num_received;

	/*	If we didn't receive any data then we're probably still polling to get connected and
		therefore not getting any data back. To avoid overloading the system with a Synergy
		thread that would hammer on polling, we let it rest for a bit if there's no data. */
	if (num_received == 0)
		context->m_sleepFunc(context->m_cookie, 500);

	/* Check for timeouts */
	if (context->m_hasReceivedHello)
	{
		uint32_t cur_time = context->m_getTimeFunc();
		if (num_received == 0)
		{
			/* Timeout after 2 secs of inactivity (we received no CALV) */
			if ((cur_time - context->m_lastMessageTime) > USYNERGY_IDLE_TIMEOUT)
				sSetDisconnected(context);
		}
		else
			context->m_lastMessageTime = cur_time;
	}

	/* Eat packets */
	for (;;)
	{
		/* Grab packet length and bail out if the packet goes beyond the end of the buffer */
		packlen = sNetToNative32(context->m_receiveBuffer);
		if (packlen+4 > context->m_receiveOfs)
			break;

		/* Process message */
		sProcessMessage(context, context->m_receiveBuffer);

		/* Move packet to front of buffer */
		memmove(context->m_receiveBuffer, context->m_receiveBuffer+packlen+4, context->m_receiveOfs-packlen-4);
		context->m_receiveOfs -= packlen+4;
	}

	/* Throw away over-sized packets */
	if (packlen > USYNERGY_RECEIVE_BUFFER_SIZE)
	{
		/* Oversized packet, ditch tail end */
		char buffer[128];
		sprintf(buffer, "Oversized packet: '%c%c%c%c' (length %d)", context->m_receiveBuffer[4], context->m_receiveBuffer[5], context->m_receiveBuffer[6], context->m_receiveBuffer[7], packlen);
		sTrace(context, buffer);
		num_received = context->m_receiveOfs-4; // 4 bytes for the size field
		while (num_received != packlen)
		{
			int buffer_left = packlen - num_received;
			int to_receive = buffer_left < USYNERGY_RECEIVE_BUFFER_SIZE ? buffer_left : USYNERGY_RECEIVE_BUFFER_SIZE;
			int ditch_received = 0;
			if (context->m_receiveFunc(context->m_cookie, context->m_receiveBuffer, to_receive, &ditch_received) == USYNERGY_FALSE)
			{
				/* Receive failed, let's try to reconnect */
				sTrace(context, "Receive failed, trying to reconnect in a second");
				sSetDisconnected(context);
				context->m_sleepFunc(context->m_cookie, 1000);
				break;
			}
			else
			{
				num_received += ditch_received;
			}
		}
		context->m_receiveOfs = 0;
	}
}


//---------------------------------------------------------------------------------------------------------------------
//	Public interface
//---------------------------------------------------------------------------------------------------------------------



/**
@brief Initialize uSynergy context
**/
void uSynergyInit(uSynergyContext *context)
{
	/* Zero memory */
	memset(context, 0, sizeof(uSynergyContext));

	/* Initialize to default state */
	sSetDisconnected(context);
}


/**
@brief Update uSynergy
**/
void uSynergyUpdate(uSynergyContext *context)
{
	if (context->m_connected)
	{
		/* Update context, receive data, call callbacks */
		sUpdateContext(context);
	}
	else
	{
		/* Try to connect */
		if (context->m_connectFunc(context->m_cookie))
			context->m_connected = USYNERGY_TRUE;
	}
}



/**
@brief Send clipboard data
**/
void uSynergySendClipboard(uSynergyContext *context, const char *text)
{
	// Calculate maximum size that will fit in a reply packet
	uint32_t overhead_size =	4 +					/* Message size */
								4 +					/* Message ID */
								1 +					/* Clipboard index */
								4 +					/* Sequence number */
								4 +					/* Rest of message size (because it's a Synergy string from here on) */
								4 +					/* Number of clipboard formats */
								4 +					/* Clipboard format */
								4;					/* Clipboard data length */
	uint32_t max_length = USYNERGY_REPLY_BUFFER_SIZE - overhead_size;
	
	// Clip text to max length
	uint32_t text_length = (uint32_t)strlen(text);
	if (text_length > max_length)
	{
		char buffer[128];
		sprintf(buffer, "Clipboard buffer too small, clipboard truncated at %d characters", max_length);
		sTrace(context, buffer);
		text_length = max_length;
	}

	// Assemble packet
	sAddString(context, "DCLP");
	sAddUInt8(context, 0);							/* Clipboard index */
	sAddUInt32(context, context->m_sequenceNumber);
	sAddUInt32(context, 4+4+4+text_length);			/* Rest of message size: numFormats, format, length, data */
	sAddUInt32(context, 1);							/* Number of formats (only text for now) */
	sAddUInt32(context, USYNERGY_CLIPBOARD_FORMAT_TEXT);
	sAddUInt32(context, text_length);
	sAddString(context, text);
	sSendReply(context);
}
