#include <VirtualServer.h>
#include <VirtualAttrib.h>

// *****************************************************************************
// * This has to be added in order to support the CenterLine Compiler.
// *****************************************************************************
VirtualServer::~VirtualServer ( void )
	{
	StringHashIterator iter(&attribHash);
	VirtualAttrib    * attrib = NULL;	
	char             * key    = NULL;
	
	iter.first();
	while((key=iter.key())!=NULL)
		{
		attrib = (VirtualAttrib *)iter.data();
		iter++;
		attribHash.remove(key);
		if(attrib!=NULL) delete attrib;
		}
	}

void VirtualServer::populateTable ( void )
	{
	char device[10];
	char attrib[10];
	char key[20];
	for(int i=0; i<10; i++)
		{
		for(int j=0; j<10; j++)
			{
			sprintf(device, "device%i", i);
			sprintf(attrib, "attrib%i", j);
			sprintf(key, "device%i attrib%i", i, j);
			attribHash.insert(key, new VirtualAttrib(device, attrib));
			}
		}
	}

void VirtualServer::processMessages ( void )
	{
	char            key[255];
	int             saveMessageFlag;
	int             sendMessageFlag;
	cdevMessage   * message;
	VirtualAttrib * attrib;
	cdevData        output;

	while(dequeue(message)==0)
		{
		// *************************************************************
		// * Note at this point a cdevTagMap has already been received
		// * from the client.  This tag map will have initialized all
		// * of the tags that are required by the service.
		// *************************************************************
		if(!strcmp(message->getMessage(), "unregister"))
			{
			sendMessageFlag = 0;
			removeClientMonitors(message->getClientID());
			}
		if(!strncmp(message->getMessage(), "get ", 4))
			{
			output.remove();
			saveMessageFlag = 0;
			sendMessageFlag = 1;

			sprintf(key, "%s %s", 
			        message->getDeviceList()[0], 
			        &message->getMessage()[4]);
			
			if((attrib = (VirtualAttrib *)attribHash.find(key))!=NULL)
				{
				attrib->getToData(&output, message->getContext());
				output.insert("resultCode", CDEV_SUCCESS);
				}
			else output.insert("resultCode", CDEV_NOTFOUND);
			}
		else if(!strncmp(message->getMessage(), "set ", 4))
			{
			output.remove();
			saveMessageFlag = 0;
			sendMessageFlag = 1;
		
			sprintf(key, "%s %s", 
			        message->getDeviceList()[0], 
			        &message->getMessage()[4]);
			
			if((attrib = (VirtualAttrib *)attribHash.find(key))!=NULL)
				{
				output.insert("resultCode", 
					      attrib->setFromData(message->getData()));
				}
			else output.insert("resultCode", CDEV_NOTFOUND);
			}
		else if(!strncmp(message->getMessage(), "monitorOn ", 10))
			{
			saveMessageFlag = 1;
			sendMessageFlag = 0;
			
			sprintf(key, "%s %s", 
			        message->getDeviceList()[0], 
			        &message->getMessage()[10]);
			
			if((attrib = (VirtualAttrib *)attribHash.find(key))!=NULL)
				{
				attrib->insertMonitor(this, message);
				}
			}
		else if(!strncmp(message->getMessage(), "monitorOff ", 11))
			{
			saveMessageFlag = 0;
			sendMessageFlag = 1;

			sprintf(key, "%s %s", 
			        message->getDeviceList()[0], 
			        &message->getMessage()[11]);
			
			if((attrib = (VirtualAttrib *)attribHash.find(key))!=NULL)
				{
				attrib->removeMonitor(this, message);
				}
			}
		else
			{
			saveMessageFlag = 0;
			sendMessageFlag = 1;
			output.insert("resultCode", CDEV_NOTFOUND);
			}
			
		if(sendMessageFlag)
			{
			message->setData(&output, 1);
			enqueue(message);
			}
		if(!saveMessageFlag) delete message;
		}
	}

int VirtualServer::fireCallback ( cdevMessage * message ) 
	{
	int        result = CDEV_SUCCESS;
	cdevData * data   = NULL;
	
	if(message && (data = message->getData())!=NULL)
		{
		data->insert("resultCode", CDEV_SUCCESS);
		result = enqueue(message);
		}
	return result;
	}

int main()
{
VirtualServer server("VIRTUAL", "TestServerX", 0, 60);
cdevServer::runServer();

return 0;
}
