/*
	$Id: CHostEntry.10.1.h,v 1.2 2003/08/29 20:35:38 dasenbro Exp $

	File:		CHostEntry.10.1..h

	Contains:	C++ class definition for Host Entry

	Written by:	Nick Brosnahan

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

 	NOT_FOR_OPEN_SOURCE <to be reevaluated at a later time>

	Change History:

		$Log: CHostEntry.10.1.h,v $
		Revision 1.2  2003/08/29 20:35:38  dasenbro
		Pickup migration of local hosts.
		
		Revision 1.1  2003/08/10 18:09:25  dasenbro
		added to export local host names.
		
		Revision 1.11  2001/06/21 19:52:48  dasenbro
		Added Change History.
		

	Projector History:

	  <ASM5>	  3/1/99	DOR		Add boolen to "SetDirty"
	  <ASM4>	 1/24/99	MED		Added a boolean to Create to prevent searching for host prefs.
		 <3>	10/30/98	DOR		Added support for 2nd ID's to host entries.  We now move host's
									onto and off of a 2nd ID list based on their "nextAttemptTime"
									value.  The outgoing threads will only visit hosts on the
									"active" host list, therefore limiting the number of hosts that
									must be visited to process outgoing mail.
		 <2>	10/29/98	DOR		Merge the expire host changes onto the main code branch.
		<26>	 9/21/98	MED		CHostEntry::Create() now takes a boolean if the record was found
									or created.
		<25>	 8/24/98	MED		Added set/get members to ignore schedule.
		<24>	  6/1/98	DOR		Remove the "kAdd" argument from Create since we no longer use
									it.
		<23>	 5/19/98	MED		Added future expansion data members.
		<22>	  5/5/98	DOR		Add ETRNConnectionFinish
		<21>	03/23/98	DOR		Mark some fields volatile to close up some  possible race
									conditions.
		<20>	 3/12/98	DOR		Print out preference error's when the forwarding DNS info is
									bad.
		<18>	  3/9/98	DOR		Move Get/Set/Clear OwnerThreadID to CDBObject.
		<17>	 2/18/98	MED		Removed CNetworkUtilities.h.
		<16>	 2/11/98	DOR		Add a parameter to ResolveTCP
		<15>	 1/12/98	MED		Added ETRN support.
		<14>	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.
		<13>	12/11/97	DOR		Calculate next connection retry frequency based on host
									preferences.
		<12>	12/10/97	DOR		Minor changes.
		<11>	 12/9/97	DOR		New log messages.
		<10>	 12/5/97	MED		Added stop now and delete host flags with getters and setters.
		 <9>	 12/4/97	DOR		Remove cached object fields, because it was too clever an idea
									for the person who coded it up (i.e. it caused lots-o-problems)
									no time to go into it here, just don't do it again.
		 <8>	 12/3/97	DOR		More tweaks.
		 <7>	 12/3/97	DOR		Merge CMXRecord changes.
		 <6>	 12/3/97	MED		Changed CInHostEntryPref to CHostEntryPref.
		 <5>	 12/3/97	MED		Combined In and Out host entry prefs.
		 <4>	 12/2/97	DOR		Add a non-persistant field to "cache" HostEntry preferences.
		 <3>	11/19/97	MED		Integrated 5.0.3 changes.
		 <2>	 10/9/97	DOR		Add two fields to CHostEntry, two ObjID fields to "point" to the
									incoming & outgoing routing preferences.

	To Do:
*/


#ifndef __CHostEntry_10_1_h__
#define __CHostEntry_10_1_h__ 1 

#include <time.h>

#include "CDBMailBaseObject.10.1.h"
#include "CMailDatabase.10.1.h"
#include "CHostEntryPref.10.1.h"

const uInt32	kDeferralInterval_10_1              = 5;	// minutes
const uInt32	kMaxDeferralInterval_10_1           = 20;	// minutes
const uTime_t	kNeverAttemptToConnectValue_10_1	= 0x7ffffff0;

typedef struct
{
	// basic
	uInt32	numMessages;
	uInt16	numMessagesThisHour;
	uInt32	numRecipients;
	uInt32	numBytesTransferred;
	
	// connections
	uInt32	numSuccessfulConnections;
	uInt32	numFailedConnections;
	
	uTime_t	lastConnectionSuccess;	// time
	uTime_t	lastConnectionFailure;	// time
	
	uTime_t	nextConnectionAttempt;	// time
	uInt32	nextDeferralInterval;	// scales from 5 minutes up to 20 minutes

	uTime_t	nextETRNTime;			// time

	uInt32	totalConnectionTime;
	uInt32  numBytesThisConnection;
	
	// throughput	
	uInt16	fShortFlags;				// Flags field 16 bits
	uInt32	fLongFlags;					// Flags field 32 bits
	uInt32	maxMessageSize;
	
	// errors
	uInt32	numBadRecipients;
} HostStatistics_10_1;


typedef struct
{
				StdDBObjHeader_10_1	fDBHeader;
				ObjID			fHostEntryID;				// this is us (denormalized)
	volatile	ObjID			fMailSpoolID;				// this is our mail spool
	volatile	ObjID			fNextSMTPRejectID;			// List of rejection
	
		// HostEntry Information
				OSType			fAddressType;				// kRFC822 or kAppleTalk
				InetDomainName	fHostName;					// Original hostname or NBPAddressString
				uInt32			fDestination;				// TCP/IP or ADSP or UUCP or Bounce
				uTime_t			fAccessTime;				// Last time accessed
	volatile	uInt32			fDestinationClass;			// keep track of local vs. Remote...
				uInt32			fIgnoreSchedule;

		// Resolution
				InetDomainName	fResolveHostName;			// Hostname or NBPAddressString to send to

				HostStatistics_10_1	fHostStatistics;
	
	volatile	ObjID			fHostPrefsID;				// ObjID of a CHostEntryPref record...
	volatile	ObjID			fRealHostDNSCacheID;
	volatile	ObjID			fResolveHostDNSCacheID;

		// Reserved
				uInt32			fReserved1;				// reserverd
				uInt32			fReserved2;				// reserverd

				StdDBObjFooter_10_1	fDBFooter;
} CHostEntryData_10_1;

// CDBMailBaseObject Constants
const uInt32 kHostEntryDataSize_10_1 = sizeof( CHostEntryData_10_1 );
const uInt32 kHostEntryVersion_10_1 = kDBCurrentVersion_10_1 + kHostEntryDataSize_10_1;
								  
class CHostEntry_10_1 : public CDBMailBaseObject_10_1
{
public:
	enum
	{
		kUnknownDestination		= '--DS',
		kTCPDestination			= 'tcDS',		// TCP/SMTP
		kADSPDestination		= 'adDS',		// ADSP/SMTP
		kUUCPDestination		= 'uuDS',		// UUCP
		kBounceDestination		= 'bnDS'		// Bounce to admin specified host
	} DestinationTransportType;
	
	enum
	{
		kDestClassUnknown	=	'none',
		kDestClassLocal		=	'locl',
		kAdminClassLocal	=	'alcl',
		kDestClassRemote	=	'rmot'
	} eDestinationClass;

	enum
	{
		kUseForwardingInformation	=	false,
		kIgnoreHostForwardingInfo	=	true
	};

	typedef enum
	{
		kFindRealHostDNSCache		= 'real',
		kFindResolveHostDNSCache	= 'rslv'
	}eDNSCacheNameType;
	
	enum
	{
		kkNoFlags			=	0x0000,
		kPrefsChanged		=	0x0001,
		k2ndIDHasBeenSet	=	0x0002,
		k2ndIDSMTPReject	=	0x0004,
		kLastShortFlagValue =	0xffff
	};

	// Static Methods
	static CHostEntry_10_1*		FindByTypeName		( OSType inAddressType, const char* inHostName );

	static CHostEntry_10_1*		Create				( OSType inAddressType, const char* inHostName, Boolean &outHostCreated, const Boolean inSetConnectionTime );
	static Boolean 				Delete				( CHostEntry_10_1* inHostEntry );
	static uInt32 				Count				( void );
	static Boolean				GetSetFields		( const eFieldDataRequest_10_1 inFieldRequest, const void *inObjDataPtr, void *outFieldData );

	virtual CHostEntryPref_10_1* FindHostEntryPref	( void );									// caller _MUST_ done the object after using the fields...

	static 	CHostEntry_10_1*	FindByID			( const	ObjID	inObjectID );
	static	CDBBaseObject_10_1*	ObjectAllocNew		( void );

	static	OSType				GetObjTypeConstant	( void ) { return kHostEntrySignature_10_1; }
	static	uInt32				GetObjVersConstant	( void ) { return kHostEntryVersion_10_1; }
	static	uInt32				GetObjSizeConstant	( void ) { return kHostEntryDataSize_10_1; }

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

	// Constructor/Destructor
					CHostEntry_10_1					( void );
		virtual    ~CHostEntry_10_1 					( void );

	CHostEntryData_10_1*		GetHostEntryData 		( void );
	void				SetDirty 				( const Boolean inForceWriteFlag = false);

	// Object IDs
	ObjID			GetHostEntryID 				( void );

	ObjID			GetMailSpoolID 				( void );
	void			SetMailSpoolID 				( ObjID inMailSpoolID );

	// HostEntry Information
	OSType			GetAddressType				( void );
	void			SetAddressType				( OSType inAddressType );
	
	uInt32			GetDestination 				( void );
	void			SetDestination 				( uInt32 inDestination );
		
	uInt32			GetDestClass 				( void );
	void			SetDestClass 				( uInt32 inDestClass );
	
	ObjID			GetHostPrefID 				( void );
	void			SetHostPrefID 				( const ObjID inInHostPrefID );
	
	ObjID			GetRealHostDNSCacheID 		( void );
	void			SetRealHostDNSCacheID 		( const ObjID inHostDNSCacheID );

	ObjID			GetResolveHostDNSCacheID 	( void );
	void			SetResolveHostDNSCacheID 	( const ObjID inHostDNSCacheID );

	void			SetNextAttemptTime			( const uTime_t inNextAttemptTime );
	void			CalcNextAttemptTime 		( const uTime_t inTime );

	const char*		GetHostName					( void );
	void			SetHostName					( const char* inHostName );
	
	uTime_t			GetAccessTime 				( void );
	void			UpdateAccessTime 			( void );
		
	// Resolution
	const char*		GetResolveHostName			( void );
	Boolean			SetResolveHostName			( const char* inHostName, Boolean &outBadName );
	
	// Statistics
	void			ResetStatistics				( void );
	HostStatistics_10_1* GetStatistics 				( void );
	void			SuccessfulConnect			( uTime_t inTime, char* inResolveHostName, uInt32 inTransport, const uInt32 inPort2Use );
	void			FailedConnect				( uTime_t inTime, char* inResolveHostName, uInt32 inTransport, const uInt32 inPortNumber, const Boolean inCalcNextAttempt );
	void			ConnectionFinished 			( char* inResolveHostName, uInt32 inMsgs, uInt32 inKBytes, uInt32 inRecipientCount, uTime_t inTime, uInt32 inTransport );
	void			ETRNConnectionFinished 		( char* inResolveHostName, const uTime_t inTime );
	uTime_t			NextConnectAt				( void );						// returns time
	void			StatAddMessage				( uInt32 inMessageSize );
	void			StatAddRecipients			( uInt32 inRecipients );
	void			StatAddBadRecipient			( void );
	void			StatAddBytes 				( uInt32 inBytes );
	void			StatSetMessagesPerHour 		( void );

	// SMTP ETRN
	uTime_t			GetNextETRNTime				( void );				// returns time
	void			SetNextETRNTime				( uTime_t inNextTime );
	void			CalcNextETRNTime			( const uTime_t inTime );
	Boolean			IsETRNOn					( void );

#if USE_APPLETALK
	// ADSP
	Boolean		ResolveADSPHost					( void );
	void		GetDDPAddress					( DDPAddress* inDDPAddress );
	void		SetDDPAddress					( DDPAddress* inDDPAddress );
#endif // USE_APPLETALK
	// MailSpool
	void		Post							( ObjID inEnvelopeID );
	void		DoExpire						( void );

	// Halt processing
	Boolean		GetGoPostal						( void );
	void		SetGoPostal						( Boolean inGoPostal );

	// Halt processing
	Boolean		GetDeleteThisHost				( void );
	void		SetDeleteThisHost				( Boolean inDeleteThisHost );

	Boolean		GetIgnoreSchedule				( void );
	void		SetIgnoreSchedule				( Boolean inIgnoreIt );

	void 		SetShortFlags					( uInt16 inShortFlags );
	uInt16 		GetShortFlags					( void );
	
	void 		SetLongFlags					( uInt32 inShortFlags );
	uInt32 		GetLongFlags					( void );

	uTime_t 	GetLastSuccessConnectTime		( const Boolean inAllowFakeNeverConnectTimeFlag  );
	void		SetLastSuccessConnectTime		( const uTime_t inTime );
	
	uTime_t 	GetLastFailedConnectTime		( const Boolean inAllowFakeNeverConnectTimeFlag  );
	void		SetLastFailedConnectTime		( const uTime_t inTime );
	
	// Persistent Fields
	CHostEntryData_10_1		fHostEntryData;

private:

#if USE_APPLETALK
	// AppleTalk
	DDPAddress			fDDPAddress;
#endif // USE_APPLETALK
	Boolean				fGoPostal;
	Boolean				fDeleteThisHost;
};

#endif 
