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

	File:	CStatMgr.h

	Contains: Model Object which keeps track of usage statistics.

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

	Written by: Claris Corporation

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

 	NOT_FOR_OPEN_SOURCE <to be reevaluated at a later time>

	Change History:

		$Log: CStatMgr.h,v $
		Revision 1.1  2003/04/20 23:29:40  dasenbro
		Initial check-in.
		
		Revision 1.10  2002/03/21 16:41:47  dasenbro
		Updated file version information.
		
		Revision 1.9  2001/06/21 20:44:46  dasenbro
		Added Change History.
		

	Projector History:

	 <ASM12>	 2/11/99	MED		Added new Fingerprint matching.
		<11>	 7/23/98	MED		Added mail admin info.
		<10>	  6/1/98	DOR		Remove the "kAdd" argument from Create since we no longer use
									it.
		 <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		Added fields to ConnectionLimits struct.
		 <5>	  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.
		 <4>	12/15/97	DOR		Update the object version to "include" the size of the
									dataportion of the object, and add an assert to "FindByID" that
									checks the version of the object.
		 <3>	11/19/97	MED		Integrated 5.0.3 changes.
		 <2>	 11/8/97	DOR		Add support for Finger, Ph, WhoIs, LDAP

	To Do:
 */


#ifndef _CSTATMGR_H
#define _CSTATMGR_H 1

#include "CDBMailBaseObject.h"
#include "CMailDatabase.h"

// Resource Constants
const	uInt32 kConnectionLimitsResType		= 'ConL';
const	uInt32 kConnectionLimitsResID		= 128;

const	uInt32 kConnectionTimeoutsResType	= 'ConT';
const	uInt32 kConnectionTimeoutsResID		= 128;


// Max Mail Admin connections
const	sInt32	kMaxMailAdminConnections	= 2;


#if PRAGMA_STRUCT_ALIGN
	#pragma options align=mac68k
#elif PRAGMA_STRUCT_PACKPUSH
	#pragma pack(push, 2)
#elif PRAGMA_STRUCT_PACK
	#pragma pack(2)
#endif

// Old (pre 6.2) fingerprint struct
typedef struct
{
	uInt32	fAccountID;
	uInt32	fSeconds;
	uInt32	fTicks;
	uInt32	fRandom;
} sFingerPrint;

typedef struct
{
	/*  1 */	uInt16	version;
	/*  2 */	uInt32	startupOverhead; 	//	 512K	- includes finger partition
	/*  3 */	uInt32	smtpInMaxConn;		//	1024	- Upper max of incoming SMTP connections
	/*  4 */	uInt32	smtpOutMaxConn;		//	  64	- Upper max of outgoing SMTP connections
	/*  5 */	uInt32	piapMaxConn;		//	2048	- Upper max of "PIAP" (POP, IMAP & PASS) connections
	/*  6 */	uInt32	fingerMaxConn;		//	  16	- Upper max of Finger connections
	/*  7 */	uInt32	smtpInPercentage;	//	  25%	- Incoming SMTP partition
	/*  8 */	uInt32	smtpOutPercentage;	//	   5%	- 
	/*  9 */	uInt32	piapPercentage;		//	  70%	- 
	/* 10 */	uInt32	slopPercentage;		//	  10%	- 
	/* 11 */	uInt32	dbCachePercentage;	//	  15%	- 
	/* 12 */	uInt32	smtpInMemoryUse;	//	  64K	- 
	/* 13 */	uInt32	smtpOutMemoryUse;	//	  72K	- 
	/* 14 */	uInt32	piapMemoryUse;		//	  60K	- 
} ConnectionLimits;


typedef struct
{
	uInt32	version;
	uInt32	count;
	uInt32	smtpTimeout;
	uInt32	pop3Timeout;
	uInt32	passTimeout;
	uInt32	imapTimeout;
	uInt32	fingerTimeout;
} ConnectionTimeouts;


#if PRAGMA_STRUCT_ALIGN
	#pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
	#pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
	#pragma pack()
#endif

typedef struct {
	StdDBObjHeader	fDBHeader;

	ObjID		mStatMgrID;

	// Connection Counts
	uInt32 		mCurPOP3InCount;
	uInt32		mCurSMTPInCount;
	uInt32		mCurSMTPOutCount;
	uInt32		mCurIMAP4Count;
	uInt32		mCurAdminCount;
	uInt32		mCurPOP3OutCount;
	uInt32		mCurETRNCount;
	
	// Reserved
	uInt32		fReserved1;				// reserverd
	uInt32		fReserved2;				// reserverd

    // Max Connection Counts
	uInt32 		mMaxPOP3InCount;
	uInt32		mMaxIMAP4Count;
	uInt32		mMaxSMTPInCount;
	uInt32		mMaxSMTPOutCount;

   	// Total Connection Counts
	uInt32 		mTotalPOP3InCount;
	uInt32		mTotalSMTPInCount;
	uInt32		mTotalSMTPOutCount;
	uInt32		mTotalIMAP4Count;
	uInt32		mTotalAdminCount;
	uInt32		mTotalPOP3OutCount;
	uInt32		mTotalETRNCount;

	// Message Counts
	uInt32 		mCurrentMessages;		// Can be costly, so we cache here
	uInt32		mMaxMessages;
	uInt32		mReceivedMessages;

	uInt32		mLocalDeliveries;
	uInt32		mTCPDeliveries;
	uInt32		mADSPDeliveries;
	uInt32		mUUCPDeliveries;

	// DB Sizes
	uInt32			mDBDataLength;			// persistent sum of data size

	StdDBObjFooter	fDBFooter;
} CStatMgrData;

// CDBMailBaseObject Constants
const uInt32 kStatMgrDataSize = sizeof(CStatMgrData);
const uInt32 kStatMgrVersion = kDBCurrentVersion + kStatMgrDataSize;


typedef enum {
	kADSPSMTPLimit = 'smtp',
	kADSPPOP3Limit = 'pop3',
	kADSPPASSLimit = 'pass'
} ADSPHackSelector;


typedef struct
{
	uInt32 adspSMTPLimit;
	uInt32 adspPOP3Limit;
	uInt32 adspPASSLimit;
} ADSPHack;


class CStatMgr : public CDBMailBaseObject
{
friend class CStatistics;

public:
	enum {
		kSMTPInConnection,
		kSMTPOutConnection,
		kPOP3InConnection,
		kPOP3OutConnection,
		kPASSConnection,
		kIMAP4Connection,
		kFingerConnection,
		kAdminConnection,
		kETRNConnection
	};

	// Static Methods
	static CStatMgr* 	Find				( ObjID inStatMgrID );
	static CStatMgr*	Create				( void );
	static uInt16		GetMaxConnections	( uInt32 inType, Boolean inUseADSPHack, Boolean inReCalc );
	static uInt32		GetTimeout			( uInt32 inConnectionType );
	static Boolean		GetSetFields		( const eFieldDataRequest inFieldRequest, const void *inObjDataPtr, void *outFieldData );

	static 	CStatMgr*		FindByID			( const	ObjID	inObjectID );
	static	CDBBaseObject*	ObjectAllocNew		( void );

	static	OSType		GetObjTypeConstant	( void ) { return kStatMgrSignature; }
	static	uInt32		GetObjVersConstant	( void ) { return kStatMgrVersion; }
	static	uInt32		GetObjSizeConstant	( void ) { return kStatMgrDataSize; }

	virtual	ObjID		GetObjectID			( void );
	virtual	void		ChkCompilerStructAlignment ( void );
		void			Done				( CStatMgr* &inPtr );

						CStatMgr			( void );
	virtual 		   ~CStatMgr			( void );

		ObjID			GetStatMgrID		( void );
		CStatMgrData*	GetStatMgrData		( void );
		void			ClearStats			( Boolean inMarkDirtyFlag = true );

		void			AddConnection		( uInt32 inConnectionType, Boolean inMarkDirtyFlag = true );
		void			RemoveConnection	( uInt32 inConnectionType, Boolean inMarkDirtyFlag = true );

		void			AddMessage			( Boolean inMarkDirtyFlag = true );
		void			RemoveMessage		( Boolean inMarkDirtyFlag = true );

		enum
		{
			kLocalDelivery,
			kTCPDelivery,
			kADSPDelivery,
			kUUCPDelivery
		};

		void	MessageReceived				( Boolean inMarkDirtyFlag = true );
		void	RecipientDelivered			( uInt32 inDestination, Boolean inMarkDirtyFlag = true );

		enum
		{
			kStatCurPOP3InCount,
			kStatMaxPOP3InCount,
			kStatTotalPOP3InCount,
			kStatCurSMTPInCount,
			kStatMaxSMTPInCount,
			kStatTotalSMTPInCount,
			kStatCurSMTPOutCount,
			kStatMaxSMTPOutCount,
			kStatTotalSMTPOutCount,
			kStatCurIMAP4Count,
			kStatMaxIMAP4Count,
			kStatTotalIMAP4Count,
			kStatCurAdminCount,
			kStatMaxAdminCount,
			kStatTotalAdminCount,
			kStatCurPOP3OutCount,
			kStatTotalPOP3OutCount,
			kStatCurETRNCount,
			kStatTotalETRNCount,
			kStatCurMailInCount,

			kStatCurMessages,
			kStatMaxMessages,
			kStatReceivedMessages,
			kStatLocalDeliveries,
			kStatTCPDeliveries,
			kStatADSPDeliveries,
			kStatUUCPDeliveries,

			kStatRunningClock,
			kStatStartTime
		};

		uInt32	GetStat (uInt32 inStatType);
		static time_t InitStartTime(void);

		void	IncrementDBDataLength (uInt32 inAddDataLength, Boolean inMarkDirtyFlag = true);
		void	DecrementDBDataLength (uInt32 inRemoveDataLength, Boolean inMarkDirtyFlag = true);
		uInt32	GetDBDataLength (void);

		void SetDirty (void);

private:
	CStatMgrData	fStatMgrData;

	// Times
	static uInt32		sStartClock;			// in seconds
	static uInt32		sStartTime;				// from ::time(NULL)

};

// ---------------------------------------------------------------------------

extern CStatMgr* gStatMgr;

#endif
