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

	File:		CMailSpool.h

	Contains:	C++ class definitions for generic mail spool objects

	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: CMailSpool.h,v $
		Revision 1.1  2003/04/20 23:45:34  dasenbro
		Initial check-in.
		
		Revision 1.10  2002/03/21 16:41:23  dasenbro
		Updated file version information.
		
		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:

	  <ASM5>	  3/1/99	MED		Removed the member functions that handled the unseen count.  It
									is now calculated on the fly.
	  <ASM4>	 1/24/99	MED		Added getters and setters for the TOC mark.
		 <3>	10/22/98	MED		Added RemoveUser() to remove the user even if the shared spool
									doesn't exist.
		 <2>	10/12/98	MED		Added RemoveGroupSharedSpools() to delete all shared group
									mailboxes.
		<27>	 10/6/98	MED		Added IsSpoolInList().
		<26>	 9/17/98	MED		Changed CanSetACL to IsAdmin.
		<25>	 9/14/98	MED		Added more ACL member functions.
		<24>	  9/8/98	MED		Added a shared spool type.
		<23>	 8/31/98	MED		Constructor now takes an account ID arg to force a 2nd ID page
									createion in the db.
		<22>	 8/18/98	MED		Added kPublishedFlag.
		<21>	 8/10/98	MED		Added more support of ACLs.
		<20>	  8/3/98	MED		6.1 - Added ACL supporting calls.
		<19>	 7/25/98	MED		Added ACL stuff.
		<18>	 6/15/98	MED		#2245243 - Added a change flag to spool for updating env-info
									flags.
		<17>	  6/1/98	DOR		Remove the "kAdd" argument from Create since we no longer use
									it.
		<16>	 5/19/98	MED		Added future expansion data members.
		<15>	 4/28/98	MED		Added a refcount to keep track of number of IMAP "Selects"
									against each mailbox.
		<14>	  4/8/98	MED		FindByParentID now takes a boolean to check for case sensitive
									name matching or not.
		<13>	 3/28/98	MED		Added a POP user lock flag and getter and setter for it.
		<12>	03/23/98	DOR		Mark some data fields volatile.
		<10>	 3/10/98	DOR		CMailSpool::Remove changed, make adjustments in how we call it..
		 <9>	 3/10/98	DOR		Remove Outgoing & IMAP Spool
		 <8>	  3/3/98	MED		Added a persistent "Recent" mark to the spool for recent message
									counting.
		 <7>	  3/2/98	MED		Added an Unseen count to the persistent data and its getters and
									setters.
		 <6>	  2/4/98	MED		Added more spool flags and a ResetSpoolCounts member.
		 <5>	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.
		 <4>	 12/3/97	MED		Added outEnvInfoID arg to Post().
		 <3>	 11/5/97	MED		Added spool flags.
		 <2>	 10/9/97	MED		Modified the session stamp.

	To Do:
*/


#ifndef _CMAILSPOOL_H
#define _CMAILSPOOL_H 1

#include "CDBMailBaseObject.h"
#include "CEnvelopeInfo.h"
#include "CACLObject.h"

const uInt32 kMaxSpoolNameLength = 255;

class		CACLObject;
class		CSharedFlags;
class		DSMailUser;

typedef struct
{
	StdDBObjHeader	fDBHeader;

				ObjID		fMailSpoolID;		// this is us (denormalized)
				ObjID		fParentID;			// this is our parent (or kRootParent if we are at root)
				ObjID		fAccountID;			// this is the account that owns us

	// Reserved
				uInt32		fReserved1;
				uInt32		fReserved2;

	// ACL
				ObjID		fACLHeadID;			// Head pointer to ACL object list
				ObjID		fSharedID;

	// MailSpool Information
				OSType		fSpoolType;
				char		fSpoolName[ kMaxSpoolNameLength + 1 ];
	volatile	uInt32		fSpoolCount;
	volatile	uInt32		fSpoolSize;
				uInt32		fSharedFlags;		// Now used for Shared folder rights ( was fChangeCount )
	volatile	ObjID		fLastEnvIDPosted;	// this is used for duplicate supression, prevents
												// us from having to search the entire mail spool.
	// IMAP Information
	volatile	uInt32		fRecentCount;
	volatile	uInt32		fDeletedCount;
	volatile	uInt32		fUnseenCount;
	volatile	ObjID		fRecentMark;
	volatile	uInt32		fNextUID;
	volatile	uInt32		fFlags;

	StdDBObjFooter	fDBFooter;
} CMailSpoolData;


// CDBMailBaseObject Constants
const uInt32 kMailSpoolDataSize = sizeof( CMailSpoolData );
const uInt32 kMailSpoolVersion = kDBCurrentVersion + kMailSpoolDataSize;


class CMailSpool : public CDBMailBaseObject
{
public:
	typedef enum
	{
		// Unknown Spool
		kUnknownSpool		= '--SP',

		// System Spool
		kSystemSpool		= 'SysS',
		
		// User Spools
		kPOP3Spool			= 'p3SP',	// POP3 Mailbox
		kIMAP4InBoxSpool	= 'i4SP',	// IMAP4 Inbox Spool
		kIMAP4Spool			= 'imSP',	// IMAP4 Mailbox Spool
		
		// System Spools
		kIncomingSpool		= 'inSP',	// Incoming Routing
		kHostSpool			= 'hoSP',	// Routing == TCP/SMTP, ADSP/SMTP, or UUCP

		// Shared Spools
		kSharedSpool		= 'Shrd'

	} MailSpoolType;
	
	enum
	{
		kRootParent 	 = 1,
		kSystemAccountID = 2,
		kSharedParent	 = 3,
		kSharedAccountID = 4
	};

	typedef enum
	{
		kSubscribedFlag		= 0x00000001,
		kNoSelectFlag		= 0x00000002,
		kNoInferiorsFlag	= 0x00000004,
		kDeletedFlag		= 0x00000008,
		kSharedFlag			= 0x00000010,
		kPublishedFlag		= 0x00000020
	};

	typedef enum
	{
		kACLMask		= 0x0000FFFF,
		kACLLookup		= 0x00000001,
		kACLRead		= 0x00000002,
		kACLKeepSeen	= 0x00000004,
		kACLWrite		= 0x00000008,
		kACLInsert		= 0x00000010,
		kACLPost		= 0x00000020,
		kACLCreate		= 0x00000040,
		kACLDelete		= 0x00000080,
		kACLAdmin		= 0x00000100,
		kACLAllRights	= 0x000001FF
	};

	// Static Methods
	static CMailSpool*	FindSystemSpool 	( uInt32 inSystemSpoolType );
	static CMailSpool*	FindByNameParentID	( char *inName, ObjID inParentID, ObjID inAccountID, Boolean inCaseSensitive );
	static CMailSpool*	FindSharedByName	( char *inName, Boolean inCaseSensitive );
	static CMailSpool*	Create				( uInt32 inMailSpoolType,
											  const char* inMailSpoolName,
											  ObjID inAccountID		= kSystemAccountID,
											  ObjID inParentID		= kRootParent );

	static Boolean 		Delete			( CMailSpool* inMailSpool );
	static uInt32		Count			( void );
	static void			VerifyAll		( void );
	static Boolean		GetSetFields	( const eFieldDataRequest inFieldRequest,
										  const void *inObjDataPtr,
										  void *outFieldData );

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

	static	OSType		GetObjTypeConstant	( void ) { return kMailSpoolSignature; }
	static	uInt32		GetObjVersConstant	( void ) { return kMailSpoolVersion; }
	static	uInt32		GetObjSizeConstant	( void ) { return kMailSpoolDataSize; }

	virtual	ObjID		GetObjectID			( void );
	virtual	void		ChkCompilerStructAlignment			( void );

	// Construction/Destruction
				CMailSpool				( ObjID inAccountID = 0, uInt32 inMailSpoolType = kUnknownSpool );
	virtual	   ~CMailSpool				( void );

	void		Done					( CMailSpool* &inPtr );

	// Object IDs 
	ObjID		GetMailSpoolID			( void );
	void		SetMailSpoolID			( ObjID inSpoolID );

	ObjID		GetParentID				( void );
	void		SetParentID				( ObjID inParentID );

	ObjID		GetAccountID			( void );
	void		SetAccountID			( ObjID inAccountID );
	
	ObjID		GetLastEnvIDPosted		( void );
	void		SetLastEnvIDPosted		( ObjID inEnvelopeID );
	
	// MailSpool Information 
	OSType		GetMailSpoolType		( void );
	void		SetMailSpoolType		( OSType inType );
	
	const char*	GetMailSpoolName		( void );
	void		SetMailSpoolName		( const char* inName );

	void		IncrementSpoolCount		( void );
	void		DecrementSpoolCount		( void );

	uInt32		GetUnseenCount			( void );
	void		SetUnseenCount			( uInt32 inCount );

	void		IncrementUnseenCount	( void );
	void		DecrementUnseenCount	( void );

	void		IncrementSpoolSize		( uInt32 inAmount );
	void		DecrementSpoolSize		( uInt32 inAmount );

	uInt32		GetSpoolCount			( void );			// Number of CEnvelopeInfo objects
	uInt32		GetSpoolSize			( void );			// Sum of sizes of CEnvelope objects

	// IMAP getters and setters
	uInt32		CalcRecentCount			(  ObjID inRecentMark = 0xFFFFFFFF );

	uInt32		GetDeletedCount			( void );
	void		SetDeletedCount			( uInt32 inCount );
	void		IncrementDeletedCount	( void );
	void		DecrementDeletedCount	( void );

	void		ResetSpoolCounts		( void );

	void		VerifyData				( void );

	uInt32		GetNextUID				( void );
	void		SetNextUID				( uInt32 inNextUID );

	uInt32		GetSpoolStamp			( Boolean inReset = false );
	void		SetSpoolStamp			( void );

	uInt32		GetChangeFlag			( Boolean inReset = false );
	void		SetChangeFlag			( void );

	ObjID		GetRecentMark			( Boolean inReset );

	void		SetFlags				( uInt32 inFlags );
	uInt32		GetFlags				( void );

	void		SetPopLock				( Boolean inLock ) { fPopLock = inLock; };
	Boolean		GetPopLock				( void ) { return( fPopLock ); };

	void		IncrementRefCount		( void );
	void		DecrementRefCount		( void );
	sInt16		GetRefCount				( void );

	void		SetTOCMark				( ObjID inTocMark );
	ObjID		GetTOCMark				( void );

	// Posting/Removal/Moving/Copying
	Boolean 	Post					( ObjID inEnvelopeID, DSMailUser *inUser, Boolean inDoSuppress, ObjID &outEnvInfoID );
	Boolean 	Remove					( CEnvelopeInfo	*inEnvInfo );
	void		MoveEnvelopes			( CMailSpool *inTargetSpool );
	void		CopyEnvelopInfos		( CMailSpool *inTargetSpool, DSMailUser *inUser );

	// CEnvelopeInfo Iterator Methods
	SDBIterator*	GetEnvelopeInfoIterator		( void );
	void			ReleaseEnvelopeInfoIterator	( SDBIterator* &inIterator );
	void			DeleteAllEnvelopeInfos		( void );
	void			DeleteAllSharedSpools		( void );
	void			RemoveGroupSharedSpools		( void );

	CMailSpoolData*		GetMailSpoolData		( void );
	void				SetDirty				( void );

	// ACL
	uInt32			GetACLRights				( void );
	void			SetACLRights				( uInt32 inNewRights );

	Boolean			IsAdmin						( void );
	Boolean			SetACL						( ObjID inAcctID, ObjID inShrdSpoolID, uInt32 inRights );
	Boolean			DeleteACL					( ObjID inAcctID, ObjID inShrdSpoolID );
	Boolean			GetACLData					( ObjID inUserId, SACLInfo &outData );
	Boolean			RemoveUser					( ObjID inUserID );

	Boolean			IsUserInACLList				( ObjID inUserID, SACLInfo *outACLData );
	Boolean			IsSpoolInList				( ObjID inSpoolID );
	Boolean			IsObjectInSeenList			( ObjID inObjID );

	uInt32			GetACLHeadID				( void );
	void			SetACLHeadID				( uInt32 inNewValue );

	uInt32			GetSharedID					( void );
	void			SetSharedID					( uInt32 inNewValue );

//	uInt32			GetUnused1					( void );
//	void			SetUnused1					( uInt32 inNewValue );
	
//	uInt32			GetUnused2					( void );
//	void			SetUnused2					( uInt32 inNewValue );
	
	Boolean			GetNextACLObj				( CACLObject **inObjPtr, Boolean inCreate = false );
	Boolean			GetNextSharedObj			( CSharedFlags **inObjPtr, Boolean inCreate = false );

	void			AddToSeenList				( ObjID inObjID );
	void			ClearSeenFlags				( void );
	void			RemoveFromSeenList			( ObjID inObjID );

protected:

	CMailSpoolData	fMailSpoolData;

	uInt32		fSessionStamp;
	uInt32		fChangeFlag;
	sInt16		fRefCount;
	Boolean		fPopLock;
};

#endif /* _MAILSPOOL_H */
