/////////////////////////////////////////////////////////////////////////////
// DebugThread.cpp
//

#include "StdAfx.h"
#include "DxbDebugQueue.h"
#include "DebugThread.h"
#include "net.h"
#include <io.h>

#define CHECK_CANCEL	{if (WAIT_OBJECT_0 == WaitForSingleObject(pInfo->hShutdownEvent,0)){Error = "Canceled";	goto ErrorExit;}}

UINT DebugThread( LPVOID pParam )
{
	// Pray that pParam points to one of these...
	DEBUG_INFO_T * pInfo = (DEBUG_INFO_T *)pParam;
	CString Error;
	CDxbDebugQueue Queue;
	SOCKET socket;

	CHECK_CANCEL;

	*pInfo->pMessage = "Connecting to Dxb Driver...";
	// The board's debug queue
	if (!Queue.Init(pInfo->DriverName))
	{
		Error = "Couldn't initialize queue";
		goto ErrorExit;
	}

	CHECK_CANCEL;

	*pInfo->pMessage = "Listening...";
	do
	{
		socket = OpenSocket(pInfo->Port);
		if (-1 == socket)
		{
			Error = "Connection failed, open socket error...";
			goto ErrorExit;
		}
		CHECK_CANCEL;
	}while(0 == socket);

	*pInfo->pMessage = "Connected, waiting for data...";

	CHECK_CANCEL;

	{
#define DATA_BUFFER_SIZE 1024
		char DbgBuffer[DATA_BUFFER_SIZE];
		char ScktBuffer[DATA_BUFFER_SIZE];
		int cbInDbgBuffer;
		int cbInScktBuffer;
		int cbLeft;
		int cbThisRequest;
		fd_set FdSet;
		timeval t;
		t.tv_sec = 0;//seconds
		t.tv_usec = 100000;// microseconds 1/10S
		for (;;)
		{
			FdSet.fd_count = 1;
			FdSet.fd_array[0] = socket;
			if ( 1 == select(1, &FdSet, NULL, NULL, &t))
			{
#define NO_FLAGS 0
				cbInScktBuffer = recv(socket, &ScktBuffer[0], DATA_BUFFER_SIZE, NO_FLAGS);
				if (SOCKET_ERROR == cbInScktBuffer)
				{
					Error = "Error reading from socket";
					goto ErrorExit;
				}
				if (0 < cbInScktBuffer)
				{
#ifdef REMOVED
					ASSERT(DATA_BUFFER_SIZE > cbInScktBuffer);
					ScktBuffer[cbInScktBuffer] = 0;
					Error.Format("ScktGot:%s\n", &ScktBuffer[0]);
					TRACE(Error);
#endif // #ifdef REMOVED
					*pInfo->pMessage = "Client Data";
					cbLeft = cbInScktBuffer;
					do
					{
						CHECK_CANCEL;
						cbThisRequest = Queue.WriteData(&ScktBuffer[cbInScktBuffer-cbLeft], cbLeft);
						if (-1 == cbThisRequest)
						{
							Error = "Error writing debugee queue (kme)";
							goto ErrorExit;
						}
						cbLeft -= cbThisRequest;

//REMOVED			if (0<cbLeft){TRACE("ScktBuffer Split\n");}

					}while(0 < cbLeft);
				}
			}

			CHECK_CANCEL;

			cbInDbgBuffer = Queue.ReadData(DbgBuffer, DATA_BUFFER_SIZE);
			if (0 < cbInDbgBuffer)
			{
#ifdef REMOVED
				ASSERT(DATA_BUFFER_SIZE > cbInDbgBuffer);
				DbgBuffer[cbInDbgBuffer] = 0;
				Error.Format("DbgGot:%s\n", &DbgBuffer[0]);
				TRACE(Error);
#endif // #ifdef REMOVED

				*pInfo->pMessage = "Target Data";
				cbLeft = cbInDbgBuffer;
				do
				{
					CHECK_CANCEL;
					cbThisRequest = send(socket, &DbgBuffer[cbInDbgBuffer - cbLeft], cbLeft, NO_FLAGS);
					if (SOCKET_ERROR == cbThisRequest)
					{
						Error = "Error writing debugger queue (socket)";
						goto ErrorExit;
					}
					cbLeft -= cbThisRequest;

//REMOVED		if (0<cbLeft){TRACE("DbgBuffer Split\n");}

				}while(0 < cbLeft);
			}

			CHECK_CANCEL;
		}
	}

	Error = "Thread Exiting";
ErrorExit:
	CloseSocket(socket);
	TRACE(Error + "\n");
	*pInfo->pMessage = Error;
	SetEvent(pInfo->hThreadCompleteEvent);
	return 0;
}
