/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "nsISupports.idl"
#include "MailNewsTypes2.idl"
#include "nsIDBChangeAnnouncer.idl"
#include "nsIMsgDBView.idl"

%{C++
#include "nsMsgKeyArray.h"
%}

interface nsIFileSpec;
interface nsIDBChangeListener;
interface nsIMsgDBHdr;
interface nsISimpleEnumerator;
interface nsIMsgThread;
interface nsIDBFolderInfo;
interface nsIMsgOfflineImapOperation;
interface nsIMsgFolder;
interface nsIOFileStream;
interface nsIUrlListener;
interface nsISupportsArray;

[ptr] native octetPtr(PRUint8);

typedef unsigned long nsMsgRetainByPreference;


[scriptable, uuid(063bd2ac-de85-11d4-a5b6-0060b0fc04b7)]

interface nsIMsgRetentionSettings : nsISupports
{
  const unsigned long nsMsgRetainAll = 1;
  const unsigned long nsMsgRetainByAge = 2;
  const unsigned long nsMsgRetainByNumHeaders = 3;

  attribute boolean useServerDefaults;
  attribute nsMsgRetainByPreference retainByPreference;
  attribute unsigned long daysToKeepHdrs;
  attribute unsigned long numHeadersToKeep; 

  // this is orthogonal to retaining by age or num headers, i.e., if
  // it's set, we'll only keep NNN unread messages only, or unread
  // messages less than NNN days old.
  attribute boolean keepUnreadMessagesOnly;
  // this is for keeping offline bodies.
  attribute boolean cleanupBodiesByDays;
  attribute unsigned long daysToKeepBodies;
}; 

[scriptable, uuid(86a9da90-14f1-11d5-a5c0-0060b0fc04b7)]
interface nsIMsgDownloadSettings : nsISupports
{
  attribute boolean useServerDefaults;
  attribute boolean downloadByDate;
  attribute boolean downloadUnreadOnly;
  attribute unsigned long ageLimitOfMsgsToDownload;
};

typedef long nsMsgDBCommit;

[scriptable, uuid(aa4d45d0-3956-11d3-8d76-00805f8a6617)]

interface nsMsgDBCommitType 
{
  const long kSmallCommit = 0;
  const long kLargeCommit = 1;
  const long kSessionCommit = 2;
  const long kCompressCommit = 3;
};

[ref] native nsMsgKeyArrayRef(nsMsgKeyArray);
[ptr] native nsMsgKeyArrayPtr(nsMsgKeyArray);

[scriptable, uuid(03223c50-1e88-45e8-ba1a-7ce792dc3fc3)]
interface nsIMsgDBService : nsISupports
{
    // want to remove this method from nsIMsgDatabase...
    // if a db is opened on the folder, the listener will automatically be added
    nsIMsgDatabase openFolderDB(in nsIMsgFolder aFolder, in boolean aCreate, in boolean aLeaveInvalidDB);
    nsIMsgDatabase openMailDBFromFileSpec(in nsIFileSpec aFolderName, in boolean aCreate, in boolean aLeaveInvalidDB);
    void registerPendingListener(in nsIMsgFolder aFolder, in nsIDBChangeListener aListener);
    void unregisterPendingListener(in nsIDBChangeListener aListener);
};

[scriptable, uuid(6c8db586-57ff-4a1b-bb7e-acff79d6a4ce)]

interface  nsIMsgDatabase : nsIDBChangeAnnouncer {
  void Open(in nsIFileSpec aFolderName, in boolean aCreate, in boolean aLeaveInvalidDB);
  void forceFolderDBClosed(in nsIMsgFolder aFolder);
  void Close(in boolean aForceCommit);

  void Commit(in nsMsgDBCommit commitType);
  // Force closed is evil, and we should see if we can do without it.
  // In 4.x, it was mainly used to remove corrupted databases.
  void ForceClosed();
  void clearCachedHdrs();
  void resetHdrCacheSize(in unsigned long size);

  readonly attribute nsIDBFolderInfo  dBFolderInfo;

  // get a message header for the given key. Caller must release()!

  nsIMsgDBHdr GetMsgHdrForKey(in nsMsgKey key);
  nsIMsgDBHdr getMsgHdrForMessageID(in string messageID);
  //Returns whether or not this database contains the given key
  boolean ContainsKey(in nsMsgKey key);

   // Must call AddNewHdrToDB after creating. The idea is that you create
  // a new header, fill in its properties, and then call AddNewHdrToDB.
  // AddNewHdrToDB will send notifications to any listeners.
  nsIMsgDBHdr CreateNewHdr(in nsMsgKey key);

  void AddNewHdrToDB(in nsIMsgDBHdr newHdr, in boolean notify);

  nsIMsgDBHdr CopyHdrFromExistingHdr(in nsMsgKey key, in nsIMsgDBHdr existingHdr, in boolean addHdrToDB);

  [noscript] void ListAllKeys(in nsMsgKeyArrayRef outputKeys);

  nsISimpleEnumerator EnumerateMessages();
  nsISimpleEnumerator EnumerateThreads();

  // count the total and unread msgs, and adjust global count if needed
  void syncCounts();

  nsIMsgThread GetThreadContainingMsgHdr(in nsIMsgDBHdr msgHdr) ;

  // helpers for user command functions like delete, mark read, etc.

  void MarkHdrRead(in nsIMsgDBHdr msgHdr, in boolean bRead,
                         in nsIDBChangeListener instigator);

  void MarkHdrReplied(in nsIMsgDBHdr msgHdr, in boolean bReplied,
                         in nsIDBChangeListener instigator);

  void MarkHdrMarked(in nsIMsgDBHdr msgHdr, in boolean mark,
                         in nsIDBChangeListener instigator);

  // MDN support
  void MarkMDNNeeded(in nsMsgKey key, in boolean bNeeded,
                           in nsIDBChangeListener instigator);

  // MarkMDNneeded only used when mail server is a POP3 server
  // or when the IMAP server does not support user defined
  // PERMANENTFLAGS
  boolean IsMDNNeeded(in nsMsgKey key);

  void MarkMDNSent(in nsMsgKey key, in boolean bNeeded,
                         in nsIDBChangeListener instigator);
  boolean IsMDNSent(in nsMsgKey key);

// methods to get and set docsets for ids.
  void MarkRead(in nsMsgKey key, in boolean bRead, 
                      in nsIDBChangeListener instigator);

  void MarkReplied(in nsMsgKey key, in boolean bReplied, 
                         in nsIDBChangeListener instigator);

  void MarkForwarded(in nsMsgKey key, in boolean bForwarded, 
                           in nsIDBChangeListener instigator);

  void MarkHasAttachments(in nsMsgKey key, in boolean bHasAttachments, 
                                in nsIDBChangeListener instigator);

  [noscript] void MarkThreadRead(in nsIMsgThread thread, 
					in nsIDBChangeListener instigator, in nsMsgKeyArrayPtr thoseMarked);

  void MarkThreadIgnored(in nsIMsgThread thread, in nsMsgKey threadKey, in boolean bIgnored,
                               in nsIDBChangeListener instigator);
  void MarkThreadWatched(in nsIMsgThread thread, in nsMsgKey threadKey, in boolean bWatched,
                               in nsIDBChangeListener instigator);

  boolean IsRead(in nsMsgKey key);
  boolean IsIgnored(in nsMsgKey key);
  boolean IsMarked(in nsMsgKey key);
  boolean HasAttachments(in nsMsgKey key);

  [noscript] void MarkAllRead(in nsMsgKeyArrayPtr thoseMarked);

  [noscript] void MarkReadByDate (in PRTime startDate, in PRTime endDate, in nsMsgKeyArrayPtr markedIds);

  [noscript] void DeleteMessages(in nsMsgKeyArrayPtr nsMsgKeys, in nsIDBChangeListener instigator);
  void DeleteMessage(in nsMsgKey key, 
                           in nsIDBChangeListener instigator,
                           in boolean commit);
  void DeleteHeader(in nsIMsgDBHdr msgHdr, in nsIDBChangeListener instigator,
                          in boolean commit, in boolean notify);

  // lower level routine that doesn't remove hdr from thread or adjust counts
  void RemoveHeaderMdbRow(in nsIMsgDBHdr msgHdr);

  void UndoDelete(in nsIMsgDBHdr msgHdr);

  void MarkMarked(in nsMsgKey key, in boolean mark,
                        in nsIDBChangeListener instigator);
  void MarkOffline(in nsMsgKey key, in boolean offline,
                         in nsIDBChangeListener instigator);
  void SetLabel(in nsMsgKey key, in nsMsgLabelValue label);
  void setStringProperty(in nsMsgKey aKey, in string aProperty, in string aValue);

  void MarkImapDeleted(in nsMsgKey key, in boolean deleted,
                             in nsIDBChangeListener instigator);

  readonly attribute nsMsgKey FirstNew;

  attribute nsIMsgRetentionSettings msgRetentionSettings;
  // purge unwanted message headers and/or bodies. If deleteViaFolder is
  // true, we'll call nsIMsgFolder::DeleteMessages to delete the messages.
  // Otherwise, we'll just delete them from the db.
  void applyRetentionSettings(in nsIMsgRetentionSettings aMsgRetentionSettings, 
                              in boolean aDeleteViaFolder);

  attribute nsIMsgDownloadSettings msgDownloadSettings;

  boolean HasNew();  
  void ClearNewList(in boolean notify);
  void AddToNewList(in nsMsgKey key);

  // used mainly to force the timestamp of a local mail folder db to
  // match the time stamp of the corresponding berkeley mail folder,
  // but also useful to tell the summary to mark itself invalid
  // Also, if a local folder is being reparsed, summary will be invalid
  // until the reparsing is done.
  attribute boolean summaryValid;

  // batching - can be used to cache file stream for local mail,
  // and perhaps to use the mdb batching mechanism as well.
  void StartBatch();
  void EndBatch();
  // offline operations - we could move these into an offline operation interface
  // but it would have to be in nsMailDatabase, since local folders can be move destinations
  nsIMsgOfflineImapOperation GetOfflineOpForKey(in nsMsgKey messageKey, in boolean create);
  void  RemoveOfflineOp(in nsIMsgOfflineImapOperation op);
  nsISimpleEnumerator EnumerateOfflineOps();
  [noscript] void ListAllOfflineOpIds(in nsMsgKeyArrayPtr offlineOpIds);
  [noscript] void ListAllOfflineDeletes(in nsMsgKeyArrayPtr offlineDeletes);
  [noscript] void ListAllOfflineMsgs(in nsMsgKeyArrayPtr offlineMsgs);

  void setAttributesOnPendingHdr(in nsIMsgDBHdr pendingHdr, in string property, 
                                  in string propertyVal, in long flags);

  readonly attribute nsMsgKey lowWaterArticleNum;
  readonly attribute nsMsgKey highWaterArticleNum;
  attribute nsMsgKey nextPseudoMsgKey;   //for undo-redo of move pop->imap
  readonly attribute nsMsgKey nextFakeOfflineMsgKey; // for saving "fake" offline msg hdrs
  // for sorting
  [noscript] void createCollationKey(in AString sourceString, out octetPtr key, out unsigned long len);
  [noscript] long compareCollationKeys(in octetPtr key1, in unsigned long len1, in octetPtr key2, in unsigned long len2);

  // when creating a view, the default sort order and view flags 
  // use these for the default.  (this allows news to override, so that
  // news can be threaded by default)
  readonly attribute nsMsgViewFlagsTypeValue defaultViewFlags;
  readonly attribute nsMsgViewSortTypeValue  defaultSortType;
  readonly attribute nsMsgViewSortOrderValue defaultSortOrder;

  // for msg hdr hash table allocation. controllable by caller to improve folder loading preformance.
  attribute unsigned long msgHdrCacheSize;

  // extremely deprecated - this is going away when we get rid of nsFileSpec and friends.
  // and it's [noscript] though I don't know if you can make an attribute noscript.
  attribute nsIOFileStream folderStream;

  /**
   * The list of messages currently in the NEW state.
   * 
   * If there are no such messages, a null pointer may be returned.
   * the caller should free when done using nsMemory::Free.
   */
  void getNewList(out unsigned long count, [array, size_is(count)] out nsMsgKey newKeys);
  
  // These are used for caching search hits in a db, to speed up saved search folders.
  nsISimpleEnumerator getCachedHits(in string aSearchFolderUri);
  void refreshCache(in string aSearchFolderUri, in unsigned long aNumKeys, [array, size_is (aNumKeys)] in nsMsgKey aNewHits,
     out unsigned long aNumBadHits, [array, size_is(aNumBadHits)] out nsMsgKey aStaleHits);
  void updateHdrInCache(in string aSearchFolderUri, in nsIMsgDBHdr aHdr, in boolean aAdd);
  boolean hdrIsInCache(in string aSearchFolderUri, in nsIMsgDBHdr aHdr);

};

