/*
	$Id: CStatMgr.cpp,v 1.1 2003/04/20 23:29:40 dasenbro Exp $

	File:	CStatMgr.cpp

	Contains: Maintains program statistics

	Version:	Apple Mail Server - Mac OS X :  $Revision: 1.1 $

	Written by: Claris Corporation

	Copyright:	© 1996-2001 by Apple Computer, Inc., all rights reserved.

 	NOT_FOR_OPEN_SOURCE <to be reevaluated at a later time>

	Change History:

		$Log: CStatMgr.cpp,v $
		Revision 1.1  2003/04/20 23:29:40  dasenbro
		Initial check-in.
		
		Revision 1.19  2002/06/04 17:34:53  dasenbro
		Added UnLockTheCache() to the catch().
		
		Revision 1.18  2002/05/30 16:54:37  dasenbro
		Syntax changes.
		
		Revision 1.17  2002/03/21 16:41:47  dasenbro
		Updated file version information.
		
		Revision 1.16  2002/01/14 17:04:09  dasenbro
		Initial S4 updates.
		
		Revision 1.15  2001/06/21 20:51:10  dasenbro
		Updated file header info.
		
		Revision 1.14  2001/06/21 20:09:54  dasenbro
		Added Change History.
		

	Projector History:

	 <ASM19>	 3/22/99	MED		Check that both finger prints are non-zero.
	 <ASM18>	 2/18/99	rds		[2306316]  Fixed MatchFingerPrints. Now resets flag when new
									account match fails and old account match is attempted.
	 <ASM17>	 2/11/99	MED		Added new Fingerprint matching.
		<16>	 9/21/98	DOR		Change all uses of "Assert_" to "MailAssert"..
		<15>	 7/23/98	MED		Added mail admin stuff.
		<14>	  6/3/98	MED		locked all static handles.
		<13>	  6/2/98	MED		Changed connection partition allocations.
		<12>	  6/1/98	DOR		Remove the "kAdd" argument from Create since we no longer use
									it.
		<11>	  6/1/98	DOR		Lock the cache when doing a find.
		<10>	  6/1/98	MED		Changed ::Create to be a more kinder and gentler ::Create.
		 <9>	 5/19/98	MED		Added future expansion data members.
		 <8>	 4/29/98	MED		Added a recalc boolean to GetMaxConnections().
		 <7>	 4/28/98	MED		Modified GetMaxConnections to generate the correct number of
									connections.
		 <6>	03/23/98	DOR		Remove DeleteAllEnvelopes.
		 <5>	 3/14/98	DOR		Close up a race condition in ::Create..
		 <3>	  2/3/98	MED		Did some clean-up to OSUtil.cp and moved the functions the
									classes that called them and this is one of those classes.
		 <2>	 11/8/97	DOR		Add support for Finger, Ph, WhoIs, LDAP

	To Do:
 */


// App
#include "MailGlobals.h"
#include "CStatMgr.h"
#include "Database.h"
#include <time.h>
#include "CEnvelope.h"
#include "CEnvelopeInfo.h"
#include "COSUtils.h"
#include "CGlobals.h"


extern long gStartupMem;

CStatMgr* gStatMgr = nil;
uInt32 CStatMgr::sStartClock = 0;
uInt32 CStatMgr::sStartTime = 0;

//--------------------------------------------------------------------------------------------------
//	* GetSetFields
// 
//--------------------------------------------------------------------------------------------------

Boolean	CStatMgr::GetSetFields	(const eFieldDataRequest inFieldRequest, const void *inObjDataPtr, void *outFieldData)
{
	Boolean			result = false;
	CStatMgrData	*theData = (CStatMgrData *) inObjDataPtr;
	CStatMgr		*aTempObject	= NULL;
	ObjID			*anObjIDPtr = (ObjID *) outFieldData;

	switch (inFieldRequest)
	{
		case kSetObjID:
			theData->mStatMgrID = *anObjIDPtr;
			break;

		case kObjectPINGRequest:
			// cause the objects constructor to get called, so we force a check of
			// the struct alignment...
			aTempObject = new CStatMgr;
			delete aTempObject;
			break;

		case k2ndIDTargetChk:
			// fall through...

		default:
			result = false;
			break;
	}

	return result;
} // GetSetFields



//--------------------------------------------------------------------------------------------------
//	* GetObjectID
// 
//--------------------------------------------------------------------------------------------------

ObjID CStatMgr::GetObjectID	( void )
{
	return fStatMgrData.mStatMgrID;
} // GetObjectID


//--------------------------------------------------------------------------------------------------
//	 Done
//
//--------------------------------------------------------------------------------------------------

void CStatMgr::Done ( CStatMgr* &inPtr )
{
	CDBBaseObject *aDBObject = (CDBBaseObject *) inPtr;
	aDBObject->Done(aDBObject);

	inPtr = (CStatMgr *)aDBObject;

}


//--------------------------------------------------------------------------------------------------
//	* GetStatMgrData
// 
//--------------------------------------------------------------------------------------------------

CStatMgrData* CStatMgr::GetStatMgrData ( void )
{
	if (this != nil)
	{
		return &(this->fStatMgrData);
	}
	else
	{
		return nil;
	}
} // GetStatMgrData



//--------------------------------------------------------------------------------------------------
//	* SetDirty
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::SetDirty	( void )
{
	if ((this != nil) && (this->GetStatMgrID() != 0))
	{
		setDirty();
	}
} // SetDirty



//--------------------------------------------------------------------------------------------------
//	* ObjectAllocNew
// 
//--------------------------------------------------------------------------------------------------

CDBBaseObject * CStatMgr::ObjectAllocNew ( void )
{
	return new CStatMgr;
} // ObjectAllocNew



//--------------------------------------------------------------------------------------------------
//	* FindByID
// 
//--------------------------------------------------------------------------------------------------

CStatMgr* CStatMgr::FindByID ( const ObjID inObjectID )
{
	return (CStatMgr *) CDBMailBaseObject::MailUniversalFindByID(	inObjectID,
														CStatMgr::GetObjTypeConstant(),
														CStatMgr::GetObjVersConstant(),
														CStatMgr::GetObjSizeConstant(),
														CStatMgr::ObjectAllocNew		);
} // FindByID



//--------------------------------------------------------------------------------------------------
//	* Find
// 
//--------------------------------------------------------------------------------------------------

CStatMgr* CStatMgr::Find ( ObjID inStatMgrID )
{
	try
	{
		CStatMgr	*theStatMgr = new CStatMgr;
		OSErr		result		= kNoErr;

		if (theStatMgr != nil)
		{
			(gDB->GetBaseObjectCachePtr())->LockTheCache(CStatMgr::GetObjTypeConstant());

			result = gDB->GetObjData(kStatMgrSignature, inStatMgrID, theStatMgr->GetStatMgrData());
			if ( result != kNoErr )
			{
				delete theStatMgr;
				theStatMgr = nil;
			}
			else
			{
				theStatMgr->Use();
			}

			(gDB->GetBaseObjectCachePtr())->UnLockTheCache(CStatMgr::GetObjTypeConstant());
		}

		return( theStatMgr );
	}

	catch ( long err )
	{
		(gDB->GetBaseObjectCachePtr())->UnLockTheCache(CStatMgr::GetObjTypeConstant());

		return( nil );
	}
} // Find



//--------------------------------------------------------------------------------------------------
//	* Create
// 
//--------------------------------------------------------------------------------------------------


CStatMgr* CStatMgr::Create ( void )
{
	CStatMgr	*theStatMgr = new CStatMgr;
	OSErr		result = kNoErr;
	ObjID		aStatMgrID = 0;

	try
	{
		ThrowIfMemFail_ (theStatMgr);

		(gDB->GetBaseObjectCachePtr())->LockTheCache(CStatMgr::GetObjTypeConstant());

		result = gDB->CreateObj(kStatMgrSignature, aStatMgrID, theStatMgr->GetStatMgrData());

		if ( result == CMailDatabase::kDBNoErr )
		{
			theStatMgr->Use();
			// Initialize it
			theStatMgr->ClearStats();
			theStatMgr->SetDirty();
		}
		else
		{
			delete theStatMgr;
			theStatMgr = nil;
		}

		(gDB->GetBaseObjectCachePtr())->UnLockTheCache(CStatMgr::GetObjTypeConstant());
	}

	catch ( long err )
	{
		(gDB->GetBaseObjectCachePtr())->UnLockTheCache(CStatMgr::GetObjTypeConstant());
	}

	return( theStatMgr );

} // Create



//--------------------------------------------------------------------------------------------------
//	* CStatMgr
// 
//--------------------------------------------------------------------------------------------------

CStatMgr::CStatMgr() :
	CDBMailBaseObject(	&fStatMgrData.fDBHeader,
				&fStatMgrData.fDBFooter,
				&fStatMgrData,
				CStatMgr::GetObjTypeConstant(),
				CStatMgr::GetObjVersConstant(),
				CStatMgr::GetObjSizeConstant() )
{
	fStatMgrData.mStatMgrID			= 0;

	// Connection Counts
	fStatMgrData.mCurPOP3InCount	= 0;
	fStatMgrData.mMaxPOP3InCount	= 0;
	fStatMgrData.mTotalPOP3InCount	= 0;
	fStatMgrData.mCurIMAP4Count		= 0;
	fStatMgrData.mMaxIMAP4Count		= 0;
	fStatMgrData.mTotalIMAP4Count	= 0;
	fStatMgrData.mCurSMTPInCount	= 0;
	fStatMgrData.mMaxSMTPInCount	= 0;
	fStatMgrData.mTotalSMTPInCount	= 0;
	fStatMgrData.mCurSMTPOutCount	= 0;
	fStatMgrData.mMaxSMTPOutCount	= 0;
	fStatMgrData.mTotalSMTPOutCount	= 0;
	fStatMgrData.mCurAdminCount		= 0;
	fStatMgrData.mTotalAdminCount	= 0;
	fStatMgrData.mCurPOP3OutCount	= 0;
	fStatMgrData.mTotalPOP3OutCount = 0;
	fStatMgrData.mCurETRNCount		= 0;
	fStatMgrData.mTotalETRNCount	= 0;

	// Message Counts	-- constructor must always clear these because ClearStats() does not
	fStatMgrData.mCurrentMessages	= 0;
	fStatMgrData.mMaxMessages		= 0;
	fStatMgrData.mReceivedMessages	= 0;

	// Delivery
	fStatMgrData.mLocalDeliveries	= 0;
	fStatMgrData.mTCPDeliveries		= 0;
	fStatMgrData.mADSPDeliveries	= 0;
	fStatMgrData.mUUCPDeliveries	= 0;

	fStatMgrData.mDBDataLength		= 0;

	// Reserved
	fStatMgrData.fReserved1	= kReservedConst;
	fStatMgrData.fReserved2	= kReservedConst;

	this->ChkCompilerStructAlignment();
} // CStatMgr



//--------------------------------------------------------------------------------------------------
//	* ~CStatMgr
// 
//		- The default destructor does nothing.
//
//--------------------------------------------------------------------------------------------------

CStatMgr::~CStatMgr()
{
} // 



void	CStatMgr::ChkCompilerStructAlignment	( void )
{
	/*
		this dump was aquired by using the MPW command DumpSYM - TTE from the .xsym file produced
		from a Code Warrior Pro 1 Release Build of the AppleShare IP Mail Server for MacOS version 6.2

		this version of the structure is consider the "reference" standard for all future ASIP Mail Servers.
		If the structure does NOT match these offsets the version of the Mail Server that 
		you are compiling will _NOT_ be compatible with AppleShare IP 6.0, 6.1, or 6.2 (this also effects
		the AppleShare IP Mail Tool, and to a more limited extent the AppleShare IP Mail Admin since some
		of these structures are passed across the wire..)

		If _ANY_ of these Asserts "fire" you've got a backwards compatibility problem that _MUST_ be fixed!!

		this code wasn't put here for my personal amusement, this code was put here from a hard earned lesson
		that simple changes to headers/compilers _WILL_ break this stuff, better to know now than after we
		ship.  Look upon this code as a debugging AIDE, not an impediment.

		Type Name:  CStatMgrData		TINFO offset: 51188		(TINFO SYM file offset (hex): $1247F4)
			RecordOf 
			offset 0 NamedTypeOf fDBHeader TypeDef of "Type ID 248"
			offset 12 NamedTypeOf mStatMgrID 
			offset 16 NamedTypeOf mCurPASSCount unsigned short 
			offset 18 NamedTypeOf mCurPOP3Count 
			offset 20 NamedTypeOf mCurSMTPInCount unsigned short 
			offset 22 NamedTypeOf mCurSMTPOutCount 
			offset 24 NamedTypeOf mCurIMAP4Count unsigned short 
			offset 26 NamedTypeOf mCurFingerCount 
			offset 28 NamedTypeOf fReserved1 unsigned long 
			offset 32 NamedTypeOf fReserved2 
			offset 36 NamedTypeOf mStartClock unsigned long 
			offset 40 NamedTypeOf mStartTime 
			offset 44 NamedTypeOf mMaxPASSCount unsigned short 
			offset 46 NamedTypeOf mMaxPOP3Count 
			offset 48 NamedTypeOf mMaxIMAP4Count unsigned short 
			offset 50 NamedTypeOf mMaxSMTPInCount 
			offset 52 NamedTypeOf mMaxSMTPOutCount unsigned short 
			offset 54 NamedTypeOf mMaxFingerCount 
			offset 56 NamedTypeOf mCurrentMessages unsigned long 
			offset 60 NamedTypeOf mMaxMessages 
			offset 64 NamedTypeOf mReceivedMessages unsigned long 
			offset 68 NamedTypeOf mLocalDeliveries 
			offset 72 NamedTypeOf mTCPDeliveries unsigned long 
			offset 76 NamedTypeOf mADSPDeliveries 
			offset 80 NamedTypeOf mUUCPDeliveries unsigned long 
			offset 84 NamedTypeOf mDBDataLength 
			offset 88 NamedTypeOf fDBFooter TypeDef of "Type ID 250"
	*/
	static Boolean	aRunOnceFlag = false;
	if (aRunOnceFlag == false)
	{
		//FileFormatSaftyChk(CStatMgrData, fDBHeader,		0);
		//FileFormatSaftyChk(CStatMgrData, mStatMgrID,		12);		// this is us (denormalized)
		//FileFormatSaftyChk(CStatMgrData, mCurPASSCount,	16);
		//FileFormatSaftyChk(CStatMgrData, mCurPOP3Count,	18);
		//FileFormatSaftyChk(CStatMgrData, mCurSMTPInCount,20);
		//FileFormatSaftyChk(CStatMgrData, mCurSMTPOutCount,22);
		//FileFormatSaftyChk(CStatMgrData, mCurIMAP4Count,	24);
		//FileFormatSaftyChk(CStatMgrData, mCurFingerCount,26);
		//FileFormatSaftyChk(CStatMgrData, fReserved1,		28);
		//FileFormatSaftyChk(CStatMgrData, fReserved2,		32);
		//FileFormatSaftyChk(CStatMgrData, mStartClock,	36);			// in ticks
		//FileFormatSaftyChk(CStatMgrData, mStartTime,		40);				// from ::time(NULL)
		//FileFormatSaftyChk(CStatMgrData, mMaxPASSCount,	44);
		//FileFormatSaftyChk(CStatMgrData, mMaxPOP3Count,	46);
		//FileFormatSaftyChk(CStatMgrData, mMaxIMAP4Count,	48);
		//FileFormatSaftyChk(CStatMgrData, mMaxSMTPInCount,50);
		//FileFormatSaftyChk(CStatMgrData, mMaxSMTPOutCount,52);
		//FileFormatSaftyChk(CStatMgrData, mMaxFingerCount,54);
		//FileFormatSaftyChk(CStatMgrData, mCurrentMessages,56);		// Can be costly, so we cache here
		//FileFormatSaftyChk(CStatMgrData, mMaxMessages,	60);
		//FileFormatSaftyChk(CStatMgrData, mReceivedMessages,64);
		//FileFormatSaftyChk(CStatMgrData, mLocalDeliveries,68);
		//FileFormatSaftyChk(CStatMgrData, mTCPDeliveries,	72);
		//FileFormatSaftyChk(CStatMgrData, mADSPDeliveries,76);
		//FileFormatSaftyChk(CStatMgrData, mUUCPDeliveries,80);
		//FileFormatSaftyChk(CStatMgrData, mDBDataLength,	84);			// persistent sum of data size
		//FileFormatSaftyChk(CStatMgrData, fDBFooter,		88);
//		this->ReportBackwardCompatibility(sizeof(CStatMgrData),	92,	"CStatMgrData", "SIZEOF()");
//		this->ReportBackwardCompatibility(kStatMgrDataSize,	92,	"CStatMgrData", "kStatMgrDataSize");
	}

	aRunOnceFlag = true;
}

//--------------------------------------------------------------------------------------------------
//	* ClearStats
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::ClearStats ( Boolean inMarkDirtyFlag )
{
	// Connection Counts
	fStatMgrData.mCurPOP3InCount	= 0; 
	fStatMgrData.mMaxPOP3InCount	= 0;
	fStatMgrData.mTotalPOP3InCount	= 0;
	fStatMgrData.mCurIMAP4Count		= 0;
	fStatMgrData.mMaxIMAP4Count		= 0;
	fStatMgrData.mTotalIMAP4Count	= 0;
	fStatMgrData.mCurSMTPInCount	= 0;
	fStatMgrData.mMaxSMTPInCount	= 0;
	fStatMgrData.mTotalSMTPInCount	= 0;
	fStatMgrData.mCurSMTPOutCount	= 0;
	fStatMgrData.mMaxSMTPOutCount	= 0;
	fStatMgrData.mTotalSMTPOutCount	= 0;
	fStatMgrData.mCurAdminCount		= 0;
	fStatMgrData.mTotalAdminCount	= 0;
	fStatMgrData.mCurPOP3OutCount	= 0;
	fStatMgrData.mTotalPOP3OutCount	= 0;
	fStatMgrData.mCurETRNCount		= 0;
	fStatMgrData.mTotalETRNCount	= 0;

	// We make sure that the message counts are valid
	uInt32 currEnvelopes	 = CEnvelope::Count();
	uInt32 currEnvelopeInfos = CEnvelopeInfo::Count();

	if ( currEnvelopeInfos == 0 )		// there should be no messages in the system
	{
		fStatMgrData.mCurrentMessages = currEnvelopes;
	}
	else
	{	// xxx ANC this assert fails when using a poorly closed database
		fStatMgrData.mCurrentMessages = currEnvelopes;
	}

	// No need to mess with mMaxMessages or mReceivedMessages

	// Delivery counts
	fStatMgrData.mLocalDeliveries	= 0;
	fStatMgrData.mTCPDeliveries		= 0;
	fStatMgrData.mADSPDeliveries	= 0;
	fStatMgrData.mUUCPDeliveries	= 0;

	if ( inMarkDirtyFlag )
	{
		this->SetDirty();
	}
} // ClearStats



//--------------------------------------------------------------------------------------------------
//	* AddConnection
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::AddConnection ( uInt32 inConnectionType, Boolean inMarkDirtyFlag )
{
    if ( this != NULL )
    {
        switch (inConnectionType)
		{
			case kPOP3InConnection:
				fStatMgrData.mCurPOP3InCount++;
				fStatMgrData.mTotalPOP3InCount++;
				if (fStatMgrData.mCurPOP3InCount > fStatMgrData.mMaxPOP3InCount)
				{
					fStatMgrData.mMaxPOP3InCount = fStatMgrData.mCurPOP3InCount;
				}
				break;
	
			case kPOP3OutConnection:
				fStatMgrData.mCurPOP3OutCount++;
				fStatMgrData.mTotalPOP3OutCount++;
				break;
	
			case kSMTPInConnection:
				fStatMgrData.mCurSMTPInCount++;
				fStatMgrData.mTotalSMTPInCount++;
				if ( fStatMgrData.mCurSMTPInCount > fStatMgrData.mMaxSMTPInCount )
				{
					fStatMgrData.mMaxSMTPInCount = fStatMgrData.mCurSMTPInCount;
				}
				break;
	
			case kSMTPOutConnection:
				fStatMgrData.mCurSMTPOutCount++;
				fStatMgrData.mTotalSMTPOutCount++;
				if ( fStatMgrData.mCurSMTPOutCount > fStatMgrData.mMaxSMTPOutCount )
				{
					fStatMgrData.mMaxSMTPOutCount = fStatMgrData.mCurSMTPOutCount;
				}
				break;
	
			case kIMAP4Connection:
				fStatMgrData.mCurIMAP4Count++;
				fStatMgrData.mTotalIMAP4Count++;
				if (fStatMgrData.mCurIMAP4Count > fStatMgrData.mMaxIMAP4Count)
				{
					fStatMgrData.mMaxIMAP4Count = fStatMgrData.mCurIMAP4Count;
				}
				break;
	
			case kAdminConnection:
				fStatMgrData.mCurAdminCount++;
				fStatMgrData.mTotalAdminCount++;
				break;
	
			case kETRNConnection:
				fStatMgrData.mCurETRNCount++;
				fStatMgrData.mTotalETRNCount++;
				break;
	
			default:
				break;
		}

		if ( inMarkDirtyFlag )
		{
			this->SetDirty();
		}

        this->ReleaseObjectLock(true);
    }
} // AddConnection



//--------------------------------------------------------------------------------------------------
//	* RemoveConnection
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::RemoveConnection (uInt32 inConnectionType, Boolean inMarkDirtyFlag)
{
    if ( this != NULL )
    {
        switch ( inConnectionType )
	{
		case kPOP3InConnection:
			ThrowIf_ (fStatMgrData.mCurPOP3InCount < 1);
			fStatMgrData.mCurPOP3InCount--;
			break;

		case kPOP3OutConnection:
			ThrowIf_ (fStatMgrData.mCurPOP3OutCount < 1);
			fStatMgrData.mCurPOP3OutCount--;
			break;

		case kSMTPInConnection:
			ThrowIf_ ( fStatMgrData.mCurSMTPInCount < 1 );
			fStatMgrData.mCurSMTPInCount--;
			break;

		case kSMTPOutConnection:
			ThrowIf_ ( fStatMgrData.mCurSMTPOutCount < 1 );
			fStatMgrData.mCurSMTPOutCount--;
			break;

		case kIMAP4Connection:
			ThrowIf_ (fStatMgrData.mCurIMAP4Count < 1);
			fStatMgrData.mCurIMAP4Count--;
			break;

		case kAdminConnection:
			fStatMgrData.mCurAdminCount--;
			break;

		case kETRNConnection:
			ThrowIf_ (fStatMgrData.mCurETRNCount < 1);
			fStatMgrData.mCurETRNCount--;
			break;

		default:
			break;
	}

	if (inMarkDirtyFlag)
	{
		this->SetDirty();
	}

        this->ReleaseObjectLock(true);
    }
} // RemoveConnection



//--------------------------------------------------------------------------------------------------
//	* AddMessage
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::AddMessage ( Boolean inMarkDirtyFlag )
{
    if ( this != NULL )
    {
        fStatMgrData.mCurrentMessages++;
	if (fStatMgrData.mCurrentMessages > fStatMgrData.mMaxMessages)
	{
		fStatMgrData.mMaxMessages = fStatMgrData.mCurrentMessages;

		if (inMarkDirtyFlag)
		{
			this->SetDirty();
		}
	}
        this->ReleaseObjectLock(true);
    }
} // AddMessage



//--------------------------------------------------------------------------------------------------
//	* RemoveMessage
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::RemoveMessage ( Boolean inMarkDirtyFlag )
{
    if ( this != NULL )
    {
        ThrowIf_ (fStatMgrData.mCurrentMessages < 1);
	fStatMgrData.mCurrentMessages--;

	if (inMarkDirtyFlag)
	{
		this->SetDirty();
	}
        this->ReleaseObjectLock(true);
    }
} // RemoveMessage



//--------------------------------------------------------------------------------------------------
//	* MessageReceived
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::MessageReceived ( Boolean inMarkDirtyFlag )
{
    if ( this != NULL )
    {
        fStatMgrData.mReceivedMessages++;

	if (inMarkDirtyFlag)
	{
		this->SetDirty();
	}
        this->ReleaseObjectLock(true);
    }
} // MessageReceived



//--------------------------------------------------------------------------------------------------
//	* RecipientDelivered
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::RecipientDelivered ( uInt32 inDestination, Boolean inMarkDirtyFlag )
{
    if ( this != NULL )
    {
        switch (inDestination)
	{
		case kLocalDelivery:
			fStatMgrData.mLocalDeliveries++;
			break;
		case kTCPDelivery:
			fStatMgrData.mTCPDeliveries++;
			break;
		case kADSPDelivery:
			fStatMgrData.mADSPDeliveries++;
			break;
		case kUUCPDelivery:
			fStatMgrData.mUUCPDeliveries++;
			break;
		default:
			break;
	}

	if (inMarkDirtyFlag)
	{
		this->SetDirty();
	}
        this->ReleaseObjectLock(true);
    }
} // RecipientDelivered



//--------------------------------------------------------------------------------------------------
//	* GetStat
// 
//--------------------------------------------------------------------------------------------------

uInt32 CStatMgr::GetStat ( uInt32 inStatType )
{
	uInt32	result = 0;

	switch ( inStatType )
	{
		// Connection Counts

		// POP
		case kStatCurPOP3InCount:
			result = fStatMgrData.mCurPOP3InCount;
			break;

		case kStatMaxPOP3InCount:
			result = fStatMgrData.mMaxPOP3InCount;
			break;

		case kStatTotalPOP3InCount:
			result = fStatMgrData.mTotalPOP3InCount;
			break;

		case kStatCurPOP3OutCount:
			result = fStatMgrData.mCurPOP3OutCount;
			break;

		case kStatTotalPOP3OutCount:
			result = fStatMgrData.mTotalPOP3OutCount;
			break;

		// SMTP
	    case kStatCurSMTPInCount:
	    	result = fStatMgrData.mCurSMTPInCount;
			break;

	    case kStatTotalSMTPInCount:
	    	result = fStatMgrData.mTotalSMTPInCount;
			break;

	    case kStatCurSMTPOutCount:
	    	result = fStatMgrData.mCurSMTPOutCount;
			break;

	    case kStatMaxSMTPOutCount:
	    	result = fStatMgrData.mMaxSMTPOutCount;
			break;

	    case kStatTotalSMTPOutCount:
	    	result = fStatMgrData.mTotalSMTPOutCount;
			break;

		// IMAP
		case kStatCurIMAP4Count:
			result = fStatMgrData.mCurIMAP4Count;
			break;

		case kStatMaxIMAP4Count:
			result = fStatMgrData.mMaxIMAP4Count;
			break;

		case kStatTotalIMAP4Count:
			result = fStatMgrData.mTotalIMAP4Count;
			break;

		// Admin
		case kStatCurAdminCount:
			result = fStatMgrData.mCurAdminCount;
			break;

		case kStatMaxAdminCount:
			result = kMaxMailAdminConnections;
			break;

		case kStatTotalAdminCount:
			result = fStatMgrData.mTotalAdminCount;
			break;

		// Mail in count
		case kStatCurMailInCount:
			result = fStatMgrData.mCurIMAP4Count + fStatMgrData.mCurPOP3InCount;
			break;

		// ETRN
		case kStatCurETRNCount:
			result = fStatMgrData.mCurETRNCount;
			break;

		case kStatTotalETRNCount:
			result = fStatMgrData.mTotalETRNCount;
			break;

		// Message Counts
		case kStatCurMessages:
			result = fStatMgrData.mCurrentMessages;
			break;

		case kStatMaxMessages:
			result = fStatMgrData.mMaxMessages;
			break;

		case kStatReceivedMessages:
			result = fStatMgrData.mReceivedMessages;
			break;

		case kStatLocalDeliveries:
			result = fStatMgrData.mLocalDeliveries;
			break;

		case kStatTCPDeliveries:
			result = fStatMgrData.mTCPDeliveries;
			break;

		case kStatADSPDeliveries:
			result = fStatMgrData.mADSPDeliveries;
			break;

		case kStatUUCPDeliveries:
			result = fStatMgrData.mUUCPDeliveries;
			break;

		// Times
		case kStatRunningClock:
			result = (::time( nil ) - sStartClock);
			break;

		case kStatStartTime:
			result = sStartTime;
			break;

		default:
			result = 0;
			break;
	}

	return ( result );
} // GetStat



//--------------------------------------------------------------------------------------------------
//	* InitStartTime
//		returns the current local time
//--------------------------------------------------------------------------------------------------

time_t CStatMgr::InitStartTime( void )
{
	sStartClock = ::time( nil );
	sStartTime = ::time( nil );

	return( sStartTime );

} // InitStartTime



// ---------------------------------------------------------------------------------------
#pragma mark * DB Sizes *
// ---------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------------------
//	* IncrementDBDataLength
// 
//--------------------------------------------------------------------------------------------------
void CStatMgr::IncrementDBDataLength ( uInt32 inAddDataLength, Boolean inMarkDirtyFlag )
{
    if ( this != NULL )
    {
        fStatMgrData.mDBDataLength += inAddDataLength;

	if (inMarkDirtyFlag)
	{
		this->SetDirty();
	}
        this->ReleaseObjectLock(true);
    }
} // IncrementDBDataLength



//--------------------------------------------------------------------------------------------------
//	* DecrementDBDataLength
// 
//--------------------------------------------------------------------------------------------------

void CStatMgr::DecrementDBDataLength ( uInt32 inRemoveDataLength, Boolean inMarkDirtyFlag )
{
    if ( this != NULL )
    {
		fStatMgrData.mDBDataLength -= inRemoveDataLength;

		if (inMarkDirtyFlag)
		{
			this->SetDirty();
		}
        this->ReleaseObjectLock(true);
    }
} // DecrementDBDataLength



//--------------------------------------------------------------------------------------------------
//	* GetDBDataLength
// 
//--------------------------------------------------------------------------------------------------

uInt32 CStatMgr::GetDBDataLength ( void )
{
	return( fStatMgrData.mDBDataLength );
} // GetDBDataLength


// ---------------------------------------------------------------------------------------
#pragma mark * Attributes from Resources *
// ---------------------------------------------------------------------------------------

const long kFlagValue = 0xFFFFFFFF;


//--------------------------------------------------------------------------------------------------
//	* GetMaxConnections ()
// 
//--------------------------------------------------------------------------------------------------

uInt16 CStatMgr::GetMaxConnections ( uInt32 inType, Boolean inUseADSPHack, Boolean inReCalc )
{
#pragma unused ( inUseADSPHack, inReCalc )

	uInt16 result;

    switch ( inType )
    {
        case kSMTPInConnection:
			result = gMaxInConnectionsSMTP;
            break;

		case kIMAP4Connection:
		case kPOP3InConnection:
			result = gMaxInConnectionsMail;
            break;

		case kETRNConnection:
		case kSMTPOutConnection:
			result = gAllowedSMTPClients;
            break;

		case kPOP3OutConnection:
			result = gAllowedPOP3Clients;
			break;

		default:
			result = 512;
			break;
    }

    return( result );

} // GetMaxConnections


//--------------------------------------------------------------------------------------------------
//	* GetStatMgrID ()
// 
//--------------------------------------------------------------------------------------------------

ObjID CStatMgr::GetStatMgrID ( void )
{
	if ( this != nil )
	{
		return( fStatMgrData.mStatMgrID );
	}

	return 0;
} // GetStatMgrID



