// We'll buffer 8K at a time for each user.
// It's smart enough not to read more data than required for the message payload.
// After that it would just start eating into the next header - so it stops.
void OTClientConnection::ReadBytesIntoBuffer()
{
	// At this point, the checksum has already validated. 
	// Might as well get the PAYLOAD next.
	int			err = 0;
	uint32_t	nread = 0;
	
	const int		nBufferSize = 8192; // todo no hardcoding.
	unsigned char	szBuffer[8300]; // I made this a little bigger just for safety reasons.
	
	memset(szBuffer, 0, 8299);  // just in case.
	
	//ultimately we want to read until m_Buffer.GetSize equals m_CMD.fields.size
	// In this function we'll read up to that or 8192, whichever is smaller.
	uint32_t	lNumberOfBytesRemaining	= m_CMD.fields.size - m_Buffer.GetSize();
	uint32_t	nNumberOfBytesToRead	= ((lNumberOfBytesRemaining > nBufferSize) ? nBufferSize : lNumberOfBytesRemaining);
	
	// actually read the payload from the socket into the buffer.
	for (nread = 0;  nread < nNumberOfBytesToRead;  nread += err)
	{
		err = SFSocketRead(m_pSocket, 
						   szBuffer + nread,
						   nNumberOfBytesToRead - nread);
		
		// if we don't read anything more, stop reading and move on
#ifdef _WIN32
		if (0 == err || SOCKET_ERROR == err) // 0 means disconnect. error means error. >0 means bytes read.
#else
		if (err <= 0)
#endif
		break;
	}
	
	// If we read anything, up to 4K, we add it to the m_Buffer.
	// This continues happening until m_Buffer.GetSize() == m_CMD.fields.size 
	// and then other code reads the message from the buffer and processes it.
	if (nread)
	{
		OTData toAddData(szBuffer, nread);
		m_Buffer += toAddData;
	}
}
// If a valid header is received, this function gets called.
// The job of this function is to creae the message, read it, and add it to m_listIn.
// ...and also, if there are unexpected bytes, to flush them in anticipation of the
// next valid message.
void OTClientConnection::ProcessMessage(u_header & theCMD)
{
	bool bSuccess = false;
		
	OTMessage * pMsg = NULL;
	
	if ( theCMD.fields.type_id == CMD_TYPE_1 )
	{
		fprintf(stderr, "Received a Type 1 Command...\n");
		
		if( IsChecksumValid( theCMD.buf, OT_CMD_HEADER_SIZE ) )
		{								
			fprintf(stderr, "Checksum is valid! Processing payload.\n");
			
			pMsg = new OTMessage;
			
			if (ProcessType1Cmd(theCMD, *pMsg ))
			{
				AddToInputList(*pMsg);
				bSuccess = true;
			}
			else {
				delete pMsg;
				pMsg = NULL;
			}

		}
		else
		{
			//gDebugLog.Write("Invalid checksum - Type 1 Command");
			fprintf(stderr, "Invalid checksum - Type 1 Command, header size: %d\n", OT_CMD_HEADER_SIZE);
		}
	}
	else
	{
		//gDebugLog.Write("Unknown command type");
		fprintf(stderr, "Unknown command type\n");
		
	}
	
	
	// I added this for error correction. In the event that there are errors, 
	// just clean out whatever is in the pipe and throw it away.
	// Should probably send an Error message back, as well.
	if (bSuccess == false)
	{
		int  err = 0, nread = 0;
		
		char buffer[1024];
		int sizeJunkData = 1024;
		
		while (1)
		{
			err = SFSocketRead(m_pSocket, buffer, sizeJunkData);
			
			if (err > 0)
				nread += err;

#ifdef _WIN32
			if (0 == err || SOCKET_ERROR == err) // 0 means disconnect. error means error. >0 means bytes read.
#else
			if (err <= 0)
#endif
				break;
		}
		
		fprintf(stderr, "Transmission error--%d bytes flushed.\n", nread);
		
		// we are buffering data from the pipe now, so if we flush the pipe, we
		// should flush the buffer too.
		m_Buffer.Release();
	}
	else 
	{
		// TODO still need to process the commands and send the replies somewhere...
		//if (bSuccess = theServer.ProcessUserCommand(theMessage, theReply))
		//{
	//		fprintf(stderr, "Successfully processed user command: %s\n", theMessage.m_strCommand.Get());
//			ProcessReply(ssl, theReply);
//		}
//		else
//		{
//			fprintf(stderr, "Unable to process user command in XML, or missing payload, in ProcessMessage.\n");
//		}
	}
}
void OTClientConnection::ProcessBuffer()
{	
	if (!m_bHaveHeader)
	{
		int  err, nread;
		union u_header theCMD;

		// clear the header object.	
		memset((void *)theCMD.buf, 0, OT_CMD_HEADER_SIZE);
		
		// Read the header
		for (nread = 0;  nread < OT_CMD_HEADER_SIZE;  nread += err)
		{
			err = SFSocketRead(m_pSocket, 
							   theCMD.buf + nread, OT_CMD_HEADER_SIZE - nread);

#ifdef _WIN32
			if (0 == err || SOCKET_ERROR == err) // 0 is a disconnect. error is error. otherwise err contains bytes read.
#else
			if (err <= 0)
#endif
			{
				break;
			}
			else {
				fprintf(stderr, "Reading input from socket...\n");
			}
		}
		
		if (nread == OT_CMD_HEADER_SIZE)
		{
			uint32_t lOldSize	= theCMD.fields.size;
			uint32_t lSize		= ntohl(lOldSize); // think this might be causing some problems... maybe not.
			theCMD.fields.size	= lSize; // fix the byte order.
			
			m_CMD			= theCMD;	// grab a copy of the header
			m_bHaveHeader	= true;		// We need to remember that we are now in "header mode"

			int nChecksum	= theCMD.fields.checksum;
			
			fprintf(stderr, "\n************************************************************\n===> Reading header from client message.\n"
					"First 9 bytes are: %d %d %d %d %d %d %d %d %d.\nSize is: %d...\n",
					theCMD.buf[0],theCMD.buf[1],theCMD.buf[2],theCMD.buf[3],theCMD.buf[4], 
					theCMD.buf[5], theCMD.buf[6], theCMD.buf[7], theCMD.buf[8], lSize);
			
			fprintf(stderr, "\nCMD HEADER:   CMD TYPE: %d -- CMD NUM: %d\n"
					"PAYLOAD SIZE: %d -- CHECKSUM: %d\n", theCMD.fields.type_id, 
					theCMD.fields.command_id, lSize, nChecksum);

			ReadBytesIntoBuffer();
			
			// When the server knows for SURE it is receiving a message,
			// then wait for 1 second to make sure we have the entire payload
			// at once.
			// TODO: rewrite socket code so that if a complete command has not yet
			// come in, to buffer the data and wait until next time around the loop.
			// Because right now, if you have a partial command, it reads it as an error
			// and returns, discarding what had already been read. Obviously that will
			// not work for a real server.
			// In the meantime, this sleep allows me to do testing by insuring that,
			// with a second's wait, the server will have time to read the entire message.
	//		sleep(1);
			
	//		ProcessMessage(theCMD);
		}
	}
	else {
		// If we've finally read enough into our buffer to process the entire mesage, then process it.
		if (m_Buffer.GetSize() >= m_CMD.fields.size)
		{
			ProcessMessage(m_CMD);
			m_bHaveHeader = false;
		} // otherwise if we haven't read enough, just read a bit more and wait until next time.
		else
			ReadBytesIntoBuffer();
	}

}