/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/***************************************************************************
 *            kolab-mail-access.h
 *
 *  Tue Dec 21 16:02:54 2010
 *  Copyright  2010  Christian Hilberg
 *  <hilberg@kernelconcepts.de>
 ****************************************************************************/

/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */

/*----------------------------------------------------------------------------*/

/**
 * SECTION: kolab-mail-access
 * @short_description: the Kolab2 PIM email infrastructure
 * @title: KolabMailAccess
 * @section_id:
 * @see_also: #KolabMailImapClient, #KolabMailInfoDb, #KolabMailMimeBuilder, #KolabMailSideCache, #KolabMailSynchronizer, #KolabMailHandle, #KolabSettingsHandler
 * @stability: unstable
 *
 * This class is the main Kolab2 PIM email store and server connector. It is
 * comprised of the following main objects
 * <itemizedlist>
 *   <listitem>#KolabMailImapClient -- connects with a Kolab2 IMAP server, read-only offline cache</listitem>
 *   <listitem>#KolabMailInfoDb -- keeps PIM folder and PIM email metadata</listitem>
 *   <listitem>#KolabMailMimeBuilder -- deals with MIME message parts and whole MIME messages</listitem>
 *   <listitem>#KolabMailSideCache -- read/write offline cache for PIM folders and PIM emails</listitem>
 *   <listitem>#KolabMailSynchronizer -- PIM data (and metadata) synchronization, conflict resolution</listitem>
 * </itemizedlist>
 *
 * #KolabMailAccess needs to be configured before operating it. Call
 * kolab_mail_access_configure() and supply a #KolabSettingsHandler object.
 * This defines the context #KolabMailAccess will be working in, i.e.
 * %KOLAB_FOLDER_CONTEXT_CALENDAR or %KOLAB_FOLDER_CONTEXT_CONTACT
 * (see #KolabFolderContextID).
 *
 * Operational modes of this class can be switched via calls to
 * kolab_mail_access_set_opmode(). Operational modes are defined in
 * #KolabMailAccessOpmodeID.
 *
 * In #KolabMailAccess, a "source" means an address book or a calendar.
 * Before storing/retrieving PIM data to/from a source (which is mapped to
 * some specific IMAP folder on the server side), the source needs to either
 * already exist or it must be created.
 *
 * The query functions may invalidate folder information or #KolabMailHandle
 * objects retrieved prior to the query function call. It is probably best
 * not to store #KolabMailHandle references outside #KolabMailAccess but to
 * get UID lists and get the associated handle by calling
 * kolab_mail_access_get_handle() each time a handle is needed for any
 * operation with it.
 * Each call to a query function may add new changed UIDs to an internal list.
 * This list can be retrieved once by calling kolab_mail_access_query_changed_uids().
 * Be sure to take proper care of the UIDs contained therein. A "changed" UID
 * may mean that the corresponding PIM object does no longer exist. A call
 * to kolab_mail_access_get_handle() with such a UID will return with a NULL
 * value.
 *
 * For information about the notions of "complete" and "incomplete" mail
 * handles, see #KolabMailHandle. In short, you can use an incomplete handle
 * for deletion operations only. For all else, call kolab_mail_access_retrieve_handle()
 * to complete the handle and attach the actual PIM data to it.
 *
 * #KolabMailHandle objects have a notion of being "complete" or "incomplete".
 * In the latter case, they are merely shallow objects with very little information
 * attached to them. Before operating on a #KolabMailHandle object, make sure it is
 * complete. An incomplete object can be completed by a call to kolab_mail_access_retrieve_handle()
 * which will fetch the actual data from any of the caches within #KolabMailAccess.
 * To delete a PIM object, it's #KolabMailHandle representation does not
 * need to be completed.
 *
 * The kolab_mail_access_store_handle() operation changes
 * the completeness state of a handle from complete to incomplete, as it strips
 * off the actual PIM data and stores it persistently, and so it does with
 * the handle metadata. This means that before the same handle can be used
 * further, it must be completed again (and may yield different data, e.g. if
 * the PIM data has changed on the server and we're in online operation).
 * This operation takes ownership of the #KolabMailHandle object.
 */

/*----------------------------------------------------------------------------*/

#ifndef _KOLAB_MAIL_ACCESS_H_
#define _KOLAB_MAIL_ACCESS_H_

/*----------------------------------------------------------------------------*/

#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>

#include "kolab-backend-types.h"
#include "kolab-settings-handler.h"
#include "kolab-util-backend.h"
#include "kolab-mail-handle.h"

/*----------------------------------------------------------------------------*/

G_BEGIN_DECLS

#define KOLAB_TYPE_MAIL_ACCESS             (kolab_mail_access_get_type ())
#define KOLAB_MAIL_ACCESS(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), KOLAB_TYPE_MAIL_ACCESS, KolabMailAccess))
#define KOLAB_MAIL_ACCESS_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), KOLAB_TYPE_MAIL_ACCESS, KolabMailAccessClass))
#define KOLAB_IS_MAIL_ACCESS(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KOLAB_TYPE_MAIL_ACCESS))
#define KOLAB_IS_MAIL_ACCESS_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), KOLAB_TYPE_MAIL_ACCESS))
#define KOLAB_MAIL_ACCESS_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), KOLAB_TYPE_MAIL_ACCESS, KolabMailAccessClass))

typedef struct _KolabMailAccessClass KolabMailAccessClass;
typedef struct _KolabMailAccess KolabMailAccess;

struct _KolabMailAccessClass
{
	GObjectClass parent_class;
};

struct _KolabMailAccess
{
	GObject parent_instance;
};

GType
kolab_mail_access_get_type (void) G_GNUC_CONST;

gboolean
kolab_mail_access_configure (KolabMailAccess *self,
                             KolabSettingsHandler *ksettings,
                             GError **err);

KolabSettingsHandler*
kolab_mail_access_get_settings_handler (KolabMailAccess *self);

gboolean
kolab_mail_access_bringup (KolabMailAccess *self,
                           GCancellable *cancellable,
                           GError **err);

gboolean
kolab_mail_access_shutdown (KolabMailAccess *self,
                            GCancellable *cancellable,
                            GError **err);

gboolean
kolab_mail_access_set_opmode (KolabMailAccess *self,
                              KolabMailAccessOpmodeID opmode,
                              GCancellable *cancellable,
                              GError **err);

KolabMailAccessOpmodeID
kolab_mail_access_get_opmode (KolabMailAccess *self,
                              GError **err);

GList*
kolab_mail_access_query_sources (KolabMailAccess *self,
                                 GError **err);

gboolean
kolab_mail_access_create_source (KolabMailAccess *self,
                                 const gchar *sourcename,
                                 GCancellable *cancellable,
                                 GError **err);

gboolean
kolab_mail_access_delete_source (KolabMailAccess *self,
                                 const gchar *sourcename,
                                 GCancellable *cancellable,
                                 GError **err);

gboolean
kolab_mail_access_source_fbtrigger_needed (KolabMailAccess *self,
                                           const gchar *sourcename,
                                           GError **err);

GList*
kolab_mail_access_query_uids (KolabMailAccess *self,
                              const gchar *sourcename,
                              const gchar *sexp,
                              GError **err);

GList*
kolab_mail_access_query_changed_uids (KolabMailAccess *self,
                                      const gchar *sourcename,
                                      const gchar *sexp,
                                      GCancellable *cancellable,
                                      GError **err);

const KolabMailHandle*
kolab_mail_access_get_handle (KolabMailAccess *self,
                              const gchar *uid,
                              const gchar *sourcename,
                              GCancellable *cancellable,
                              GError **err);

gboolean
kolab_mail_access_store_handle (KolabMailAccess *self,
                                KolabMailHandle *kmailhandle,
                                const gchar *sourcename,
                                GCancellable *cancellable,
                                GError **err);

gboolean
kolab_mail_access_retrieve_handle (KolabMailAccess *self,
                                   const KolabMailHandle *kmailhandle,
                                   gboolean bulk,
                                   GCancellable *cancellable,
                                   GError **err);

gboolean
kolab_mail_access_delete_handle (KolabMailAccess *self,
                                 const KolabMailHandle *kmailhandle,
                                 GCancellable *cancellable,
                                 GError **err);

gboolean
kolab_mail_access_delete_by_uid (KolabMailAccess *self,
                                 const gchar *uid,
                                 const gchar *sourcename,
                                 GCancellable *cancellable,
                                 GError **err);

G_END_DECLS

/*----------------------------------------------------------------------------*/

#endif /* _KOLAB_MAIL_ACCESS_H_ */

/*----------------------------------------------------------------------------*/
