/*
	$Id: CEnvelope.h,v 1.1 2003/04/20 23:45:34 dasenbro Exp $

	File:		CEnvelope.h

	Contains:	C++ class definition of Message Envelope container

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

	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: CEnvelope.h,v $
		Revision 1.1  2003/04/20 23:45:34  dasenbro
		Initial check-in.
		
		Revision 1.16  2002/06/13 00:57:01  dasenbro
		Added time to SetCreationTime() to preserver the received time on a DB repair.
		
		Revision 1.15  2002/06/04 18:07:45  dasenbro
		Syntax changes.
		
		Revision 1.14  2002/05/09 16:58:58  dasenbro
		Changed all str... calls to CUtils::Str... to be NULL safe.
		
		Revision 1.13  2002/04/18 18:09:12  dasenbro
		Changed bool to Bool for word alignment.
		
		Revision 1.12  2002/03/21 16:41:23  dasenbro
		Updated file version information.
		
		Revision 1.11  2002/03/05 19:49:21  dasenbro
		Added second GetData() which allowes a length parameter.
		
		Revision 1.10  2002/02/20 20:58:47  dasenbro
		Added some DB migration info to object data.
		
		Revision 1.9  2002/01/14 17:27:41  dasenbro
		Initial S4 updates.
		
		Revision 1.8  2001/06/21 20:50:58  dasenbro
		Updated file header info.
		
		Revision 1.7  2001/06/21 18:18:47  dasenbro
		Added Change History.
		

	Projector History:

		 <3>	10/21/98	DOR		Fix it so that we properly calculate the message size...
		 <2>	10/20/98	DOR		Build the message-prefix string on the fly in order to save data
									space...
		<21>	 9/24/98	DOR		Split the ViaPOP code into two values, one to indicate 822
									routing, and one to not.
		<20>	 8/21/98	DOR		Add support for new CPOPClient threads.
		<19>	  6/1/98	DOR		Remove the "kAdd" argument from Create since we no longer use
									it.
		<18>	 5/19/98	MED		Added future expansion data members.
		<17>	 4/14/98	MED		Added getters and setters for a TOC envelope string to be stored
									in the message prefix data space and added some offset and
									lenght database fields for the TOC envelope string.
		<16>	03/23/98	DOR		Remove DeleteAllEnvelopes and make some data fields volatile.
		<15>	03/23/98	DOR		ObjectLock is now part of CDBObject...
		<13>	 3/10/98	DOR		CMailSpool::Remove changed, make adjustments in how we call it..
		<12>	 2/26/98	DOR		Add a new "via" enum-type, "kDoorNail", as in dead-as-a...
		<11>	 2/23/98	MED		Changed the VTwinReference to a long.
		<10>	 2/19/98	DOR		Convert to using CFastMutex
		 <9>	 2/19/98	DOR		Use Semaphores rather than booleans to protect the CEnvelope
									structure.
		 <8>	 2/18/98	MED		Added semaphors for IMAP TOC and index creation on a per
									envelope basis.
		 <7>	  2/4/98	DOR		Merge small message part changes from a branch.
		 <6>	 1/15/98	MED		Added a server IP address so we can keep track of which IP
									address this message came in over for 822 header routing.
		 <5>	12/17/97	MED		Added some flags to the envelope.
		 <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/21/97	DOR		Add field & methods to track message warnings.
		 <2>	11/19/97	MED		Integrated 5.0.3 changes.

	To Do:
*/


#ifndef __CEnvelope_h__
#define __CEnvelope_h__	1

#include "CDBMailBaseObject.h"
#include "CMailDatabase.h"
#include "CTextObjMgr.h"
#include "CString.h"
#include "MailGlobals.h"

class CRecipient;
//class CMessagePart;

const uInt32 kMaxPathLen = 1024;		// 1K

#pragma options align=mac68k
typedef struct
{
	StdDBObjHeader	fDBHeader;

				ObjID		fEnvelopeID;				// this is us (denormalized)
	volatile	ObjID		fSenderID;					// this is our sender recipient object
	volatile	ObjID		fMsgTocID;					// message table of contents ID

	volatile	uInt32		fVTwinReference;

	
	volatile	ObjID		fRecipListHeadID;			// 
	volatile	ObjID		fMsgPartID;					// 

				TextStrObj	fDataPathObj;
				TextStrObj	fFromLineObj;
	
	// Reserved
				uInt32		fReserved1;					// reserverd
				uInt32		fReserved2;					// reserverd

	// Envelope Information
				uInt32		fViaCode;								// how did we get it
				char		fSendingHost[ kMaxHostNameLength + 1 ];	// the sending host name
				uInt32		fMessageSize;							// size in bytes of message (cached)
				uInt32		fCreationTime;							// time created
				uInt32		fWarningSentTime;						// time the Warning was sent...
				uInt32		fAttemptTime;							// last attempt at delivery
				uInt16		fTransports;							// AppleTalk, TCP/IP, or Bounce

				uInt16		fTOCEnvelopeStrOffset;					// Offset for TOC Envelope string
				uInt16		fTOCEnvelopeStrLength;					// Lenght of TOC Envelope string

				uInt16		fFilePathLen;							// Length of prepended headers
				char		fFilePath[ kMaxPathLen ];				// prepended headers + TOC Envelope string	

				uInt32		fServerIPAddr;							// server IP Address (used for multihoming)
				uInt32		fFlags;									// envelope flags

	volatile	uInt16		fSpoolRefCount;				// Number of CEnvelopeInfo objects referring to me
	volatile	uInt16		fHostRefCount;				// Number of Host Spool objects referring to me
	
	// Recipient Counts
				uInt16		fOriginalRecipientCount;	// # Before routing expansions
				uInt16		fTotalRecipientCount;		// # Currently
	
				uInt16		fPendingRecipientCount;		// # Pending Routing
				uInt16		fDeliveredRecipients;		// # Delivered To Successfully
				uInt16		fErrorRecipientCount;		// # Routing or delivery unsuccessful
	
				uInt16		fGroupRecipientCount;		// # of groups
				uInt16		fAutoForwardRecipientCount;	// # of autoforwards
				uInt16		fLocalRecipientCount;		// # of local recipients
				uInt16		fRemoteRecipientCount;		// # of remote recipients
	volatile	uInt16		fRemotePostingDone;			// true when the router is done posting the message to _ALL_ hosts

	// MessagePart Count
	volatile	uInt16		fMessagePartCount;
				uInt16		fPadding1;					// added in 6.3 to maintain format compatibility with 6.0, 6.1 & 6.2

	StdDBObjFooter	fDBFooter;
} CEnvelopeData;

#pragma options align=reset


// CDBMailBaseObject Constants
const uInt32 kEnvelopeDataSize = sizeof ( CEnvelopeData );
const uInt32 kEnvelopeVersion = kDBCurrentVersion + kEnvelopeDataSize;

// Envelope flags (more to come)
typedef enum {
	kForwardToAnyUser		= 0x00000001,
	kRequiredDotStuffing	= 0x00000002,
	kLargeMessagePart		= 0x10000000,
	kSmallMessagePart		= 0x20000000,
	kIncompleteMessage		= 0x40000000,
	kEndFlags				= 0
} envFlags;


class CEnvelope : public CDBMailBaseObject
{
public:
	typedef enum 
	{ 
		kViaUnknown					= '--VA', 
		kViaSMTP 					= 'ipVA',		// SMTP
		kViaATalk					= 'atVA',		// SMTP over ADSP
		kViaUUCP	 				= 'uuVA', 		// UUCP
		kViaNDR						= 'ndVA',		// NDR Generated
		kViaIMAP					= 'imVA',		// IMAP
		kViaNDRTwice				= 'ndV2',		// NDR has been posted to the Postmaster once before...
		kViaPOPAccountNo822Parse	= 'POP1',
		kViaPOPAccountWith822Parse	= 'POP2',
		kViaDoorNail				= 'deth'
	} ViaCodes;

	// Static Methods
	static CEnvelope *		Create					( uInt32 inViaCode, const char* inSendingHost );
	static Boolean			Delete					( CEnvelope* inEnvelope );
	static uInt32			Count					( void );
	static SDBIterator *	GetEnvelopeIterator		( void );
	static void				ReleaseEnvelopeIterator	( SDBIterator* &inIterator );
	static Boolean			GetSetFields			(const eFieldDataRequest inFieldRequest, const void *inObjDataPtr, void *outFieldData);

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

	static	OSType			GetObjTypeConstant		( void ) { return kEnvelopeSignature; }
	static	uInt32			GetObjVersConstant		( void ) { return kEnvelopeVersion; }
	static	uInt32			GetObjSizeConstant		( void ) { return kEnvelopeDataSize; }

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

	// Construction/Destruction
				CEnvelope				( void );
	virtual	   ~CEnvelope				( void );

	CEnvelopeData*	GetEnvelopeData		( void );
	void			SetDirty 			( void );

	// Object IDs
	ObjID		GetEnvelopeID			( void );

	ObjID		GetSenderID				( void );
	void		SetSenderID				( ObjID inSenderID );

	ObjID		GetMessageTocID			( void );
	void		SetMessageTocID			( ObjID inMsgTocID );

	CFile*		CreateDataFile			( void );
	CFile*		GetDataFile				( void );
	char*		GetData					( uInt32 &outLen );
	char*		GetData					( uInt32 &outLen, uInt32 inSize );

	// CEnvelope Information
	uInt32		GetViaCode				( void );
	void		SetViaCode				(uInt32 inViaCode);

	ObjID		GetMsgPartID			( void );
	void		SetMsgPartID			( ObjID inPartID );

	const char* GetSendingHost			( void );
	void		SetSendingHost			(const char* inSendingHost);

	uInt32		GetMessageSize			( void );
	void		SetMessageSize			( uInt32 inMessageSize );
	
	Boolean		GetRemotePostingFlag	( void );
	void		SetRemotePostingFlag	(Boolean inPostingFlag);

	ObjID		GetRecipListHeadID		 ( void );
	void		SetRecipientListHeadID	 ( ObjID inListHeadID );

	uInt32		GetServerIPAddr			( void );
	void		SetServerIPAddr			( uInt32 inServerIPAddr );
	
	enum {
		kSpoolReference	= 0x01,
		kHostReference	= 0x02
	};

	void		AddReference			( uInt32 inType );
	void		RemoveReference			( uInt32 inType );
	uInt32		GetRefCount				( uInt32 inType );

	enum {
		kTCPTransport	 = 0x01,
		kADSPTransport	 = 0x02,
		kBounceTransport = 0x04
	};

	void		AddTransport			( uInt16 inTransport );
	uInt16		GetTransports			( void );

	uInt32		GetEnvWarningTime		( void );
	void		SetEnvWarningTime		(const uInt32 inWarningSentTime);

	// CRecipient Methods 
	void		AddRecipient			( ObjID inRecipientID );
	void		DeleteAllRecipients		( void );
	Boolean		DeleteSender			( void );
	
	enum 
	{ 
		kOriginalCount = 1,						// Original number submitted across SMTP 
		kTotalCount, 							// Total number currently
		kPendingRoutingCount,					// Remaining to be routed
		kDeliveredCount,						// Delivered to local spool or sent by SMTP 
		kErrorCount, 							// All routing, expansion, and delivery errors
		kGroupCount, kAutoForwardCount, 		// Recipients which should be expanded
		kLocalCount, kRemoteCount 				// Destination recipients
	};
	
	uInt16			GetRecipientCount		( uInt32 inType );
	void			SetRecipientCount		( uInt32 inType, uInt16 inCount );
	void			IncrementRecipientCount	( uInt32 inType );
	void			DecrementRecipientCount	( uInt32 inType );
	
	// CMessagePart Methods 
	void			DeleteMessageTOC		( void );

	// V-Twin references
	uInt32			GetVTwinReference	( void );
	void			SetVTwinReference	( uInt32 inRef );

	// Object creation semaphore methods
	ExceptionCode	GetTOCSemaphore		( const Boolean inWaitForTOCFlag );
	void			ReleaseTOCSemaphore	( const Boolean inNotifyOtherThreadsFlag );

	ExceptionCode	GetIndexSemaphore		( const Boolean inWaitForTOCFlag );
	void			ReleaseIndexSemaphore	( const Boolean inNotifyOtherThreadsFlag );

	// Time Fields
	void			SetCreationTime		( uInt32 inTime = 0 );
	uInt32			GetCreationTime		( void );
	void			SetLastAttemptTime	( void );
	uInt32			GetLastAttemptTime	( void );
	
	// flags
	uInt32			GetEnvelopeFlags	( void );
	void			SetEnvelopeFlags	( envFlags inFlags );
	Bool			IsFlagSet			( envFlags inFlag );

	const char	   *GetDataFilePath		( void );
	void			SetDataFilePath		( const char *inFilePath );

	const char	   *GetFromLine			( void );
	void			SetFromLine			( const char *inFromLine );

	char		   *GetDataFileName		( void );
	void			DeleteDataFile		( void );

	char		   *fDataFilePath;
	char		   *fFromLine;

private:
	CEnvelopeData		fEnvelopeData;				// this portion stored on disk...
};

#endif // __CEnvelope_h__
