#include <cdevDevice.h>
#include <cdevRequestObject.h>

int getDirectoryDevices ( char ** & devices, size_t & nDevices );
int getDeviceClass ( char * device, char *& className );
void reportOnDevice ( char * device );

int main()
	{
	char ** devices;
	size_t nDevices;
	
	cdevData::insertTag(9810, "RDONLY");
	cdevData::insertTag(9811, "PV");
	cdevData::insertTag(9812, "server");
	
	if(getDirectoryDevices(devices, nDevices)==CDEV_SUCCESS)
		{
		fprintf(stdout, "     CDEV Devices in DDL     \n");
		fprintf(stdout, "=============================\n");
		for(int i=0; i<nDevices; i++)
			{
			reportOnDevice(devices[i]);
			delete devices[i];
			}
		delete devices;
		}	
	return 0;
	}


int getDirectoryDevices ( char ** & devices, size_t & nDevices )
	{
	int          result;
	cdevData     out;
	cdevDevice & dir = cdevDevice::attachRef("cdevDirectory");

	devices  = NULL;
	nDevices = 0;

	if((result = dir.send("query", NULL, out))==CDEV_SUCCESS)
		{
		out.getElems("value", &nDevices);
		devices = new char *[nDevices];
		out.get("value", devices);
		}
	return result;
	}
	
	
int getDeviceClass ( char * device, char *& className )
	{
	int      result;
	cdevData in, out;
	cdevDevice & dir = cdevDevice::attachRef("cdevDirectory");
	
	className = NULL;
	in.insert("device", device);
	if((result = dir.send("queryClass", in, out))==CDEV_SUCCESS)
		{
		out.get("value", &className);	
		}
	return result;
	}


int getClassVerbs ( char * className, char ** & verbs, size_t &nVerbs )
	{
	int      result;
	cdevData in, out;
	cdevDevice & dir = cdevDevice::attachRef("cdevDirectory");
	
	verbs  = NULL;
	nVerbs = 0;

	in.insert("class", className);
	if((result = dir.send("queryVerbs", in, out))==CDEV_SUCCESS)
		{
		out.getElems("value", &nVerbs);
		verbs = new char *[nVerbs];
		out.get("value", verbs);	
		}
	return result;
	}

int getClassAttributes ( char * className, char ** & attributes, size_t &nAttributes )
	{
	int      result;
	cdevData in, out;
	cdevDevice & dir = cdevDevice::attachRef("cdevDirectory");
	
	attributes  = NULL;
	nAttributes = 0;

	in.insert("class", className);
	if((result = dir.send("queryAttributes", in, out))==CDEV_SUCCESS)
		{
		out.getElems("value", &nAttributes);
		attributes = new char *[nAttributes];
		out.get("value", attributes);	
		}
	return result;
	}

int getClassMessages ( char * className, char ** & messages, size_t &nMessages )
	{
	int      result;
	cdevData in, out;
	cdevDevice & dir = cdevDevice::attachRef("cdevDirectory");
	
	messages  = NULL;
	nMessages = 0;

	in.insert("class", className);
	if((result = dir.send("queryMessages", in, out))==CDEV_SUCCESS)
		{
		out.getElems("value", &nMessages);
		messages = new char *[nMessages];
		out.get("value", messages);	
		}
	return result;
	}

int getServiceData ( char * device, char *message, char *&service, char *&data)
	{
	int result;
	cdevData in, out;
	cdevDevice & dir = cdevDevice::attachRef ("cdevDirectory");
	in.insert("device", device);
	in.insert("message", message);

	service = NULL;
	data    = NULL;

	if((result = dir.send("service", in, out))==CDEV_SUCCESS)
		{
		out.get("value", &service);
		out.remove();
		if((result = dir.send("serviceData", in, out))==CDEV_SUCCESS)
			{
			int              dataLen = 1;
			cdevDataIterator iter(&out);
			
			data  = (char *)malloc(dataLen);
			*data = 0;
			iter.init();
			
			while(iter.tag()!=NULL)
				{
				char *tPtr, *dPtr = NULL;
				cdevData::tagI2C(iter.tag(), tPtr);
				out.get(iter.tag(), &dPtr);
				
				dataLen += strlen(tPtr)+strlen(dPtr)+3;
				data = (char *)realloc(data, dataLen);

				sprintf(&data[strlen(data)], "%s=%s ", tPtr, dPtr);
				delete dPtr;
				++iter;
				}
			}
		else delete service;
		}
	return result;
	}

void reportOnDevice ( char * device )
	{
	int    i;
	char * className;
	char ** verbs, **attributes, **messages;
	size_t nVerbs, nAttributes, nMessages;

	getDeviceClass(device, className);
	getClassVerbs (className, verbs, nVerbs);
	getClassAttributes(className, attributes, nAttributes);
	getClassMessages(className, messages, nMessages);

	fprintf(stdout, "Device: %s\n", device);
	fprintf(stdout, "        Class     : %s\n", className);
	for(i=0; i<nVerbs; i++)
		{
		if(i==0) fprintf(stdout, "        Verbs     : %s\n", verbs[i]);
		else     fprintf(stdout, "                    %s\n", verbs[i]);
		delete verbs[i];
		}
	for(i=0; i<nAttributes; i++)
		{
		if(i==0) fprintf(stdout, "        Attributes: %s\n", attributes[i]);
		else     fprintf(stdout, "                    %s\n", attributes[i]);
		delete attributes[i];
		}
	for(i=0; i<nMessages; i++)
		{
		if(i==0) fprintf(stdout, "        Messages  : %s\n", messages[i]);
		else     fprintf(stdout, "                    %s\n", messages[i]);
		delete messages[i];
		}
	fprintf(stdout, "\n");
	delete className;
	delete verbs;
	delete attributes;
	delete messages;
	}
	
