//=========================================================================
// Summary  :
// Filename : Process.cc
// Author   : marsh
// Project  :
// Revision : 1
// Created  : 2000/08/19
// Modified : 2000/08/19
//=========================================================================
// Description :
//=========================================================================

#include <sys/sched.h>
#include "StringAttribute.h"
#include "IntegerAttribute.h"
#include "DebugAttribute.h"
#include "BooleanAttribute.h"

#include "Syslog.h"
#include "Process.h"

Process::Process( const char *processName, short stratum,
		  debug_t defaultDebug )
     : Item( processName ),
       _ifNames(2)
{
     char binaryName[64];

     _classID = PROCESS_ID;

     _port = NULL;
     _circuit = -1;

     _priority = PRIO_USER_DFLT;
     _IFName = 0;

     _pid = 0;

     _attributes.add( new IntegerAttribute("node",
	 				   "Driver node",
	 				   &_node,
	 				   1 ) );
     
     _attributes.add( new IntegerAttribute("logNode",
	 				   "Driver log node",
	 				   &_logNode,
	 				   0 ) );

     _attributes.add( new IntegerAttribute("priority",
					   "Driver priority",
					   &_priority,
					   PRIO_USER_DFLT ) );
     
     _attributes.add( new StringAttribute("server",
					  "Server binary name",
					  &_server,
					  "" ) );

     _attributes.add( new StringAttribute("driver",
					  "Driver binary name",
					  &_driver,
					  "" ) );

     _attributes.add( new StringAttribute("driver2",
					  "Driver2 binary name",
					  &_driver2,
					  "" ) );

     _attributes.add( new StringAttribute("driver3",
					  "Driver3 binary name",
					  &_driver3,
					  "" ) );

     _attributes.add( new BooleanAttribute("driverPersists",
					   "Driver 1 is persists",
					   &_driver1Persists,
					   False));
     
     _attributes.add( new BooleanAttribute("driver1Persists",
					   "Driver 1 is persists",
					   &_driver1Persists,
					   False));

     _attributes.add( new BooleanAttribute("driver1Persists",
					   "Driver 1 is persists",
					   &_driver1Persists,
					   False));
     
     _attributes.add( new DebugAttribute("debug",
					 "Debug quanitity",
					 &_processDebug,
					 defaultDebug ) );

     _attributes.add( new StringAttribute("onFault",
					 "On fault action",
					 &_onFault,
					 "ignore") );

     _attributes.add( new StringAttribute("onFailure",
					 "On failure action",
					 &_onFailure,
					 "ignore") );

}

Process::~Process()
{
    char *item;
    for (int i = 0; i < _ifNames.size(); i++) {	
	_ifNames.get(i, &item);
	clean(item);
    }
    
    clean(_server);
    clean(_driver);
    clean(_driver2);
    clean(_driver3);
    clean(_onFault);
    clean(_onFailure);
}

Boolean Process::getDriverPersists(short index)
{
    switch(index) {
    case 1:
	return _driver1Persists;
    case 2:
	return _driver2Persists;
    case 3:
	return _driver3Persists;
    default:
	return False;
    }
}

//==========================================================

char *Process::setIFName( const char *newIFName )
{
     clean( _IFName );

     _IFName = new char[ strlen(newIFName) +1 ];
     strcpy( _IFName, newIFName );

     return _IFName;
}

//==========================================================

short Process::registerIFName( const char *newIfName )
{
     if( newIfName == NULL ) return -1;

     char *namePtr = NULL;
     // Check for uniqueness
     for( int i = 0; i < _ifNames.size(); i++ ) {
	  _ifNames.get( i, &namePtr );
	  if( namePtr == NULL )
	       continue;
	  if( !stricmp( newIfName, namePtr ))
	      return i;
     }

     //     Syslog::write("Process %s now adding %s", name(), newIfName );

     short newIfLength = strlen( newIfName );

     namePtr = NULL;
     // At this point, the name should be unique.
     namePtr = new char[ newIfLength + 1 ];
     if( namePtr == NULL ) return -1;
     strncpy( namePtr, newIfName, newIfLength+1 );

     _ifNames.add( &namePtr );

     //     Syslog::write("Process %s has %d names", name(), _ifNames.size() );

     // Return the total number of interfaces registered.
     return _ifNames.size();
}

int Process::getIFByIndex( int index, char *name, int nameLen )
{
     if( (index < 0) || (index > _ifNames.size()) ) return -1;

     char *namePtr = NULL;

     _ifNames.get( index, &namePtr );

     short copyLen = min( (short)nameLen, (short)strlen( namePtr ) );
     strncpy( name, namePtr, copyLen+1 );
     return copyLen;
}

int Process::findIFByName( char *name )
{
     if( name == NULL ) return -1;

     char *namePtr = NULL;
     short ifNamesSize = _ifNames.size();
     short cmpLength;
     short nameLen = strlen( name );
     for( int i = 0; i < ifNamesSize; i++ ) {
	  _ifNames.get( i, &namePtr );
	  cmpLength = min( (short)nameLen, (short)strlen( namePtr ) );
	  if( !strnicmp( name, namePtr, cmpLength ))
	      return i;
     }

     // If you get here, you haven't found a match
     return -1;
}

Boolean Process::hasIFName( char *name )
{
     if( name == NULL ) return False;

     char *namePtr = NULL;
     short ifNamesSize = _ifNames.size();
     short cmpLength;
     short nameLen = strlen( name );
     for( int i = 0; i < ifNamesSize; i++ ) {
	  _ifNames.get( i, &namePtr );
	  cmpLength = min( (short)nameLen, (short)strlen( namePtr ) );
	  if( !strnicmp( name, namePtr, cmpLength ))
	      return True;
     }

     return False;
}

//==========================================================

short Process::invalidate( void )
{

     // Need to clean the ifname list
    char *item;
    for (int i = 0; i < _ifNames.size(); i++) {	
	_ifNames.get(i, &item);
	delete item;
    }
    
    _ifNames.clear();

     clean(_IFName);
     _pid = 0;

     return 0;
}
