#include <cdevPlatforms.h>
#include <cdevData.h>
	
class ServerInfo 
{
friend class cdevServer;

private:
	cdevData data;		
	size_t   sendPktCnt;
	size_t   recvPktCnt;
	size_t   clientCnt;
	long     pageSize;
		
public:
	ServerInfo ( char * domain, char * server, unsigned short port )
		: sendPktCnt(0), recvPktCnt(0), clientCnt(0), pageSize(0)
		{
		cdevData::addTag("username");
		cdevData::addTag("group");
		cdevData::addTag("uid");
		cdevData::addTag("gid");
		cdevData::addTag("pid");
		cdevData::addTag("program");
		cdevData::addTag("commandline");
		cdevData::addTag("starttime");
		cdevData::addTag("host");
		cdevData::addTag("server");
		cdevData::addTag("domain");
		cdevData::addTag("port");
		cdevData::addTag("os");
		cdevData::addTag("osrelease");
		cdevData::addTag("osversion");
		cdevData::addTag("machine");
		cdevData::addTag("shell");
		cdevData::addTag("sendPktCnt");
		cdevData::addTag("recvPktCnt");
		cdevData::addTag("clientCnt");
		cdevData::addTag("pctcpu");
		cdevData::addTag("datasize");
		cdevData::addTag("socket");
		
		data.insert("server",    server);
		data.insert("domain",    domain);
		data.insert("port",      port);

		#ifndef _WIN32
			struct utsname hostinfo;
			struct group  * grp;
			char * shell = getenv("SHELL");
		
			uname(&hostinfo);
			grp = getgrgid(getgid());
				
			data.insert("username",  getlogin());
			data.insert("group",     grp?grp->gr_name:(char *)"UNDEFINED");
			data.insert("uid",       (unsigned)getuid());
			data.insert("gid",       (unsigned)getgid());
			data.insert("pid",       (unsigned)getpid());
			data.insert("host",      hostinfo.nodename);
			data.insert("os",        hostinfo.sysname);
			data.insert("osrelease", hostinfo.release);
			data.insert("osversion", hostinfo.version);
			data.insert("machine",   hostinfo.machine);
			data.insert("shell",     shell?shell:(char *)"UNDEFINED");

			#if defined(__hpux)
				struct pst_status pstatData;
				pstat_getproc(&pstatData, sizeof(pstatData), 0, (int)getpid());
				data.insert("program", pstatData.pst_ucomm);
				data.insert("commandline", pstatData.pst_cmd);
				data.insert("starttime", pstatData.pst_start);

				struct pst_static pstatStatic;
				pstat_getstatic(&pstatStatic, sizeof(pstatStatic), 1, 0);
				pageSize = pstatStatic.page_size;
			#endif
		#else
			char          userNameBuf[UNLEN+1];
			unsigned long userNameLen = UNLEN;
			char          hostNameBuf[MAXHOSTNAMELEN+1];
			unsigned long hostNameLen = MAXHOSTNAMELEN;
			
			*userNameBuf = 0;
			*hostNameBuf = 0;
			
			data.insert("pid", getpid());
			if(GetUserName    (userNameBuf, &userNameLen)) data.insert("username", userNameBuf);
			if(GetComputerName(hostNameBuf, &hostNameLen)) data.insert("host", hostNameBuf);
			
			if(userNameBuf && hostNameBuf)
				{
				char          grpNameBuf[GNLEN+1];
				unsigned long grpNameLen = GNLEN;
				char          sidBuf[256];
				unsigned long sidLen     = 256;
				SID_NAME_USE  sidType;
				
				*grpNameBuf = 0;
				if(LookupAccountName(hostNameBuf, userNameBuf, 
						     sidBuf, &sidLen, grpNameBuf,
						     &grpNameLen, &sidType))
					{
					data.insert("group", grpNameBuf);
					}
				}
			
			OSVERSIONINFO osv;
			osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
			if(GetVersionEx   (&osv))
				{
				char osVersionBuf[64];
				switch(osv.dwPlatformId)
					{
					case VER_PLATFORM_WIN32s:
					data.insert("os", "WINDOWS");
					break;
					
					case VER_PLATFORM_WIN32_WINDOWS:
					if(osv.dwMinorVersion == 0)
						data.insert("os", "WINDOWS 95");
					else	data.insert("os", "WINDOWS 98");
					break;
					
					case VER_PLATFORM_WIN32_NT:
					data.insert("os", "WINDOWS NT");
					break;
					
					default:
					data.insert("os", "WIN32");
					break;
					}
				sprintf(osVersionBuf, "%d.%d", osv.dwMajorVersion, osv.dwMinorVersion);
				data.insert("osversion", osVersionBuf);
				data.insert("osrelease", ltoa(osv.dwBuildNumber));
				}
			
			SYSTEM_INFO   sysinfo;
			GetSystemInfo(&sysinfo);
			switch(sysinfo.wProcessorArchitecture)
				{
				case PROCESSOR_ARCHITECTURE_INTEL:
				data.insert("machine", "PROCESSOR_ARCHITECTURE_INTEL");
				break;
					
				case PROCESSOR_ARCHITECTURE_MIPS:
				data.insert("machine", "PROCESSOR_ARCHITECTURE_MIPS");
				break;
					
				case PROCESSOR_ARCHITECTURE_ALPHA:
				data.insert("machine", "PROCESSOR_ARCHITECTURE_ALPHA");
				break;
					
				case PROCESSOR_ARCHITECTURE_PPC:
				data.insert("machine", "PROCESSOR_ARCHITECTURE_PPC");
				break;
					
				case PROCESSOR_ARCHITECTURE_UNKNOWN:
				default:
				data.insert("machine", "PROCESSOR_ARCHITECTURE_UNKNOWN");
				break;
				}
			
			if(__argc>0)
				{
				int    i;
				char * cmdLine = NULL;
				size_t cmdLineLen = 0;
				
				data.insert("program", __argv[0]);
				for(i=0; i<__argc; i++) cmdLineLen+=strlen(__argv[i])+1;
				cmdLine = new char [cmdLineLen];
				*cmdLine = 0;
				for(i=0; i<__argc; i++) 
					{
					strcat(cmdLine, __argv[i]);
					if(i+1<__argc) strcat(cmdLine, " ");
					}
				data.insert("commandline", cmdLine);
				}

			FILETIME startTime;
			FILETIME exitTime;
			FILETIME kernelTime;
			FILETIME userTime;
			if(GetProcessTimes(GetCurrentProcess(), &startTime, &exitTime, &kernelTime, &userTime))
				{
				struct timeval tv;
				FileTimeToTimeVal(&startTime, &tv);
				data.insert("starttime", tv.tv_sec);
				}
		#endif
		}
	
	cdevData & getServerData ( void ) 
		{ 
		#if defined(__hpux)
			struct pst_status pstatData;
			pstat_getproc(&pstatData, sizeof(pstatData), 0, (int)getpid());
			data.insert("pctcpu", pstatData.pst_pctcpu);
			data.insert("datasize", pageSize*(pstatData.pst_dsize+pstatData.pst_tsize+pstatData.pst_ssize));
			data.insert("sendPktCnt", sendPktCnt);
			data.insert("recvPktCnt", recvPktCnt);
		#endif
		
		return data; 
		}

	void asciiDump ( FILE * fp = stdout )
		{
		fprintf(fp, "--------------------------------------------------------\n");
		fprintf(fp, "                Printing Server Information\n");
		fprintf(fp, "--------------------------------------------------------\n");
		
		char *         server;
		char *         domain;
		unsigned short port;
		char *         username;
		char *         group;
		unsigned       pid;
		unsigned       gid;
		unsigned       uid;
		char *         host;
		char *         os;
		char *         osrelease;
		char *         osversion;
		char *         machine;
		char *         shell;
		char *         program;
		char *         commandline;
		long           starttime;
		size_t         datasize;
		float          pctcpu;
		
		getServerData();
		
		if(data.find("domain", (void *&)domain)!=CDEV_SUCCESS) host = NULL;
		if(data.find("server", (void *&)server)!=CDEV_SUCCESS) server = NULL;
		if(data.find("username", (void * &)username)!=CDEV_SUCCESS) username = NULL;
		if(data.find("group",    (void * &)group)!=CDEV_SUCCESS) group = NULL;
		if(data.find("host", (void * &)host)!=CDEV_SUCCESS) host = NULL;
		if(data.find("os", (void * &)os)!=CDEV_SUCCESS) os = NULL;
		if(data.find("osrelease", (void * &)osrelease)!=CDEV_SUCCESS) osrelease = NULL;
		if(data.find("osversion", (void * &)osversion)!=CDEV_SUCCESS) osversion = NULL;
		if(data.find("machine", (void * &)machine)!=CDEV_SUCCESS) machine = NULL;
		if(data.find("shell", (void * &)shell)!=CDEV_SUCCESS) shell=NULL;
		if(data.find("program", (void * &)program)!=CDEV_SUCCESS) program=NULL;
		if(data.find("commandline", (void * &)commandline)!=CDEV_SUCCESS) commandline=NULL;
		if(data.get("port", &port)!=CDEV_SUCCESS) port = 0;
		if(data.get("starttime", &starttime)!=CDEV_SUCCESS) starttime = 0;
		if(data.get("pid", &pid)!=CDEV_SUCCESS) pid = 0;
		if(data.get("gid", &gid)!=CDEV_SUCCESS) gid = 0;
		if(data.get("uid", &uid)!=CDEV_SUCCESS) uid = 0;
		if(data.get("datasize", &datasize)!=CDEV_SUCCESS) datasize = 0;
		if(data.get("pctcpu", &pctcpu)!=CDEV_SUCCESS) pctcpu = (float)0.0;
		
		fprintf(fp, "=> DOMAIN         : %s\n", domain?domain:"UNDEFINED");
		fprintf(fp, "=> SERVER         : %s\n", server?server:"UNDEFINED");
		fprintf(fp, "=> LISTENING PORT : %s\n", port?ltoa(port):"UNDEFINED");
		fprintf(fp, "=> USERNAME       : %s\n", username?username:"UNDEFINED");
		fprintf(fp, "=> GROUP          : %s\n", group?group:"UNDEFINED");
		fprintf(fp, "=> USER ID        : %s\n", uid?ltoa(uid):"UNDEFINED");
		fprintf(fp, "=> GROUP ID       : %s\n", gid?ltoa(gid):"UNDEFINED");
		fprintf(fp, "=> PROCESS ID     : %s\n", pid?ltoa(pid):"UNDEFINED");
		fprintf(fp, "=> APPLICATION    : %s\n", program?program:"UNDEFINED");
		fprintf(fp, "=> COMMAND LINE   : %s\n", commandline?commandline:"UNDEFINED");
		fprintf(fp, "=> START TIME     : %s",   starttime?ctime(&starttime):"UNKNOWN\n");
		fprintf(fp, "=> HOST NAME      : %s\n", host?host:"UNKNOWN");
		fprintf(fp, "=> OS             : %s\n", os?os:"UNKNOWN");
		fprintf(fp, "=> OS VERSION     : %s\n", osversion?osversion:"UNKNOWN");
		fprintf(fp, "=> OS RELEASE     : %s\n", osrelease?osrelease:"UNKNOWN");
		fprintf(fp, "=> HARDWARE ID    : %s\n", machine?machine:"UNKNOWN");
		fprintf(fp, "=> PERCENT CPU    : %f\n", pctcpu);
		fprintf(fp, "=> RESIDENT SIZE  : %i\n", datasize);
		fprintf(fp, "=> PACKETS SENT   : %i\n", sendPktCnt);
		fprintf(fp, "=> PACKETS RECV   : %i\n", recvPktCnt);
		fprintf(fp, "=> ACTIVE CLIENTS : %i\n", clientCnt);
		fprintf(fp, "--------------------------------------------------------\n");		
		}
};
