#include <cdevServer.h>
#include <testMessages.cc>

class myServer : public cdevServer
{
private:
	IntHash TestIndexes;
	unsigned totalCount;
	
public:
	myServer ( void )
		: cdevServer(), totalCount(0)
		{
		}
		
	myServer ( char * domain, char * server, unsigned int port, double pulse )
		: cdevServer(domain, server, port, pulse), totalCount(0)
		{
		}
		
	virtual void processMessages ( void )
		{
		cdevMessage * message;
		while(dequeue(message)==0)
			{
			if(!strcmp(message->getMessage(), "register"))
				{
				int * ptr = new int;
				TestIndexes.insert((int)message->getClientID(), (void *)ptr);
				printf("Starting Testing on Client %i\n", message->getClientID());
				}
			else if(!strcmp(message->getMessage(), "unregister"))
				{
				int * ptr = NULL;
				if((ptr = (int *)TestIndexes.find((int)message->getClientID()))!=NULL)
					{
					TestIndexes.remove((int)message->getClientID());
					delete ptr;
					}
				printf("Finishing Testing on Client %i\n", message->getClientID());
				}
			else	
				{
				int  ptr    = 0;
				int *idxPtr = (int *)TestIndexes.find((int)message->getClientID());
				int  curPtr = 0;
				
				if(idxPtr == NULL)
					{
					printf("ERROR: Failed to retrieve the index for client %i\n", message->getClientID());
					idxPtr = &ptr;
					}
				if(*idxPtr >= TestMessageCount) *idxPtr = 0;
				
				if(message->getData()==NULL)
					{
					printf("ERROR: NULL data received from client %i\n", message->getClientID());
					}
				else
					{
					message->getData()->get("packetNumber", &curPtr);
					if(curPtr!=*idxPtr)	
						{
						printf("Mismatch between packet number %i and expected %i\n", curPtr, *idxPtr);
						*idxPtr = curPtr;
						}

					int mismatch = 0;
					
					if(strcmp(message->getDeviceList()[0], TestMessage[*idxPtr].getDeviceList()[0]))
						{
						printf("ERROR: Client %i mismatch on entry %i - Device \"%s\" not equal to \"%s\"\n", 
							message->getClientID(),
							*idxPtr, 
							message->getDeviceList()[0],
							TestMessage[*idxPtr].getDeviceList()[0]);
						mismatch++;
						}
					
					if(strcmp(message->getMessage(), TestMessage[*idxPtr].getMessage()))
						{
						printf("ERROR: Client %i mismatch on entry %i - Message \"%s\" not equal to \"%s\"\n",
							message->getClientID(),
							*idxPtr, 
							message->getMessage(),
							TestMessage[*idxPtr].getMessage());
						mismatch++;
						}
					
					if(message->getData()==NULL)
						{
						printf("ERROR: Client %i mismatch on entry %i - Inbound data is NULL\n", 
							message->getClientID(),
							*idxPtr);
						mismatch++;
						}
					else if(*message->getData()!=*TestMessage[*idxPtr].getData())
						{
						printf("ERROR: Client %i mismatch on entry %i - Inbound data differs from expected\n", 
							message->getClientID(),
							*idxPtr);
						printf("----------------------------- INBOUND DATA -----------------------------\n");
						message->getData()->asciiDump();
						printf("----------------------------- EXPECTED DATA ----------------------------\n");
						TestMessage[*idxPtr].getData()->asciiDump(); 
						mismatch++;
						}
					
					if(message->getContext()==NULL && TestMessage[*idxPtr].getContext()!=NULL)
						{
						printf("ERROR: Client %i mismatch on entry %i - Inbound context is NULL\n", 
							message->getClientID(),
							*idxPtr);
						mismatch++;
						}
					else if(TestMessage[*idxPtr].getContext()==NULL)
						{
						}
					else if(*message->getContext()!=*TestMessage[*idxPtr].getContext())
						{
						printf("ERROR: Client %i mismatch on entry %i - Inbound context differs from expected\n", 
							message->getClientID(),
							*idxPtr);
						printf("---------------------------- INBOUND CONTEXT ---------------------------\n");
						message->getContext()->asciiDump();
						printf("---------------------------- EXPECTED CONTEXT --------------------------\n");
						TestMessage[*idxPtr].getContext()->asciiDump(); 
						mismatch++;
						}
					
					if(mismatch) printf("\n\n");
					else	{
						totalCount++;
						if(totalCount%1000==0) printf("Transmission %i still matches correctly\n", totalCount);
						}
					(*idxPtr)++;
					}
				}
			enqueue(message);
			delete message;
			}
		}
};

int main(int argc, char ** argv)
{
char * name;
short port;

name = (argc>1)?argv[1]:(char *)"TestServer1";
port = 0;

cdevSystem::defaultSystem().setThreshold(CDEV_SEVERITY_INFO);
myServer *server = new myServer();
server->startServer("TEST", name, port, 60.0, 1);
createTestMessages();
cdevServer::runServer();
delete server;
return 0;
}
