/**************************/
/*		  ITP v1.1        */
/*	   made by iserdo     */
/*	  iserdo@gmail.com    */
/**************************/

#include <windows.h>
#include <stdio.h>

#include "../FlameProtocol/FlameProto.h"
#include "../FlameProtocol/FlameProto_Config.h"

extern char OJCMD[];

void iproto_send(char *data, unsigned short len, char code, SOCKET sock)
{
	unsigned short		sz;

	if (!data || !len)
		return;

	sz = len;
	if (code)
		sz++;

	/* send len of data first - 2 bytes */
	send(sock, (char *)&sz, 2, 0);

	/* send code */
	if (code)
		send(sock, (char *)&code, 1, 0);

	/* send actual data */
	char DEBUGOUTPUT[1024];
    sprintf(DEBUGOUTPUT, "DBG: [send|%s|]", data);
	OutputDebugStr(DEBUGOUTPUT);

	send(sock, data, len, 0);




	return;
}

int iproto_recv(indata_s *data, SOCKET sock)
{
	fd_set		fds;
	int			r;

	/* check if theres any waiting data on socket */
	FD_ZERO(&fds);
	FD_SET(sock, &fds);


	if (select(0, &fds, NULL, NULL, data->tv) == 1)
	{
		/* waiting data to be read */
		/* check if we have d_len already */
		if (data->d_len == 0)
		{
			if (data->b_len_len == 0)
			{
				/* try to receive 2 bytes */
				r = recv(sock, data->b_len, 2, 0);
			}
			else
			{
				/* try to receive 1 byte */
				r = recv(sock, &data->b_len[1], 1, 0);
			}

			if (r <= 0)
			{
				/* connection dropped */
				printf("r <= 0\n");
				return IPROTO_DEAD;
			}

			/* check if 2 bytes received in total then we are ready to receive real data */
			data->b_len_len += r;
			if (data->b_len_len == 2)
			{
				data->d_len = *(unsigned short *)data->b_len;
				if (data->d_len == 0)
				{
					/* sending data of 0 len is not allowed! */
					data->b_len_len = 0;
					printf("Got data of 0 len\n");
					return IPROTO_NN;
				}

				/* allocate memory size of d_len */
				data->memd.ptr = (char *)malloc(data->d_len);
			}
		}
		else
		{
			/* receive data into allocated memory */
			r = recv(sock, data->memd.ptr + data->memd.len, data->d_len - data->memd.len, 0);

			if (r <= 0)
			{
				printf("r2 <= 0");
				/* connection dropped */
				return IPROTO_DEAD;
			}

			data->memd.len += r;
			if (data->memd.len == data->d_len)
			{
				//printf("Got whole stream %s\n", data->memd.ptr);
				/* we have received whole stream, we can parse it now */
				return IPROTO_AVAIL;
			}
		}
	}

	return IPROTO_NN;
}

void iproto_data_reset(indata_s *data)
{
	/* set whole data struct to 0 */
	/* prepare it to be used for next stream */

	if (data->d_len > 0)
	{
		free(data->memd.ptr);
		data->memd.len = 0;
		data->d_len = 0;
	}

	data->b_len_len = 0;

	return;
}
