/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/***************************************************************************
 *            camel-kolab-imapx-folder.c
 *
 *  Tue Sep 14 11:04:17 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 main.c; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */

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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>
#include <glib/gi18n-lib.h>

#include <camel/providers/imapx/camel-imapx-summary.h>

#include "camel-kolab-imapx-store.h"
#include "camel-kolab-imapx-folder.h"

/*----------------------------------------------------------------------------*/
/* Folder metadata */

CamelKolabImapxFolderMetadata*
camel_kolab_imapx_folder_metadata_new (void)
{
	CamelKolabImapxFolderMetadata *kfmd = NULL;
	kfmd = g_new0 (CamelKolabImapxFolderMetadata, 1);
	kfmd->folder_type = KOLAB_FOLDER_TYPE_INVAL;
	return kfmd;
}

gboolean
camel_kolab_imapx_folder_metadata_free (CamelKolabImapxFolderMetadata *kfmd)
{
	if (kfmd == NULL)
		return TRUE;
	g_free (kfmd);
	return TRUE;
}

void
camel_kolab_imapx_folder_metadata_gdestroy (gpointer data)
{
	CamelKolabImapxFolderMetadata *kfmd = (CamelKolabImapxFolderMetadata *)data;
	(void)camel_kolab_imapx_folder_metadata_free (kfmd);
}

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

G_DEFINE_TYPE (CamelKolabIMAPXFolder, camel_kolab_imapx_folder, CAMEL_TYPE_IMAPX_EXTD_FOLDER)

/*----------------------------------------------------------------------------*/
/* object init */

static void
camel_kolab_imapx_folder_init (CamelKolabIMAPXFolder *self)
{
	g_assert (CAMEL_IS_KOLAB_IMAPX_FOLDER (self));
}

static void
camel_kolab_imapx_folder_dispose (GObject *object)
{
	g_assert (CAMEL_IS_KOLAB_IMAPX_FOLDER (object));

	G_OBJECT_CLASS (camel_kolab_imapx_folder_parent_class)->dispose (object);
}

static void
camel_kolab_imapx_folder_finalize (GObject *object)
{
	g_assert (CAMEL_IS_KOLAB_IMAPX_FOLDER (object));

	G_OBJECT_CLASS (camel_kolab_imapx_folder_parent_class)->finalize (object);
}

/*----------------------------------------------------------------------------*/
/* class functions */

/*----------------------------------------------------------------------------*/
/* class init */

static void
camel_kolab_imapx_folder_class_init (CamelKolabIMAPXFolderClass *klass)
{
	GObjectClass *object_class = G_OBJECT_CLASS (klass);

	/* g_type_class_add_private (klass, sizeof (CamelKolabIMAPXFolderPrivate)); */

	object_class->dispose = camel_kolab_imapx_folder_dispose;
	object_class->finalize = camel_kolab_imapx_folder_finalize;
}

/*----------------------------------------------------------------------------*/
/* API functions */

CamelKolabIMAPXFolder*
camel_kolab_imapx_folder_new (CamelKolabIMAPXStore *store,
                              const gchar *folder_dir,
                              const gchar *folder_name,
                              GError **err)
{
	/* This function is a modified dupe of camel_imapx_folder_new() in
	 * CamelIMAPXFolder.
	 * We need to dupe it in order to return a CamelIMAPXExtdFolder
	 * Upstream fixes need to be applied here, too.
	 */

	CamelFolder *folder = NULL;
	CamelIMAPXFolder *ifolder = NULL;
	CamelKolabIMAPXFolder *kfolder = NULL;
	CamelService *service = NULL;
	CamelSettings *settings = NULL;
	const gchar *short_name = NULL;
	gchar *state_file = NULL;
	gboolean filter_inbox = FALSE;
	gboolean filter_junk = FALSE;
	gboolean filter_junk_inbox = FALSE;

	g_assert (CAMEL_IS_KOLAB_IMAPX_STORE (store));
	g_assert (folder_dir != NULL);
	g_assert (folder_name != NULL);
	g_return_val_if_fail (err == NULL || *err == NULL, NULL);

	g_debug ("%s: opening imap folder '%s'\n",
	         __func__, folder_dir);

	service = CAMEL_SERVICE (store);
	settings = camel_service_get_settings (service);

	g_object_get (settings,
	              "filter-inbox", &filter_inbox,
	              "filter-junk", &filter_junk,
	              "filter-junk-inbox", &filter_junk_inbox,
	              NULL);

	short_name = strrchr (folder_name, '/');
	if (short_name)
		short_name++;
	else
		short_name = folder_name;

	kfolder = g_object_new (CAMEL_TYPE_KOLAB_IMAPX_FOLDER,
	                        "display-name", short_name,
	                        "full_name", folder_name,
	                        "parent-store", store, NULL);
	ifolder = CAMEL_IMAPX_FOLDER (kfolder);
	folder  = CAMEL_FOLDER (kfolder);

	ifolder->raw_name = g_strdup (folder_name);

	folder->summary = camel_imapx_summary_new (folder);
	if (!folder->summary) {
		g_set_error (err,
		             CAMEL_ERROR, CAMEL_ERROR_GENERIC,
		             _("Could not create folder summary for %s"),
		             short_name);
		return NULL;
	}

	ifolder->cache = camel_data_cache_new (folder_dir, err);
	if (!ifolder->cache) {
		g_prefix_error (err,
		                _("Could not create cache for %s: "),
		                short_name);
		return NULL;
	}

	state_file = g_build_filename (folder_dir, "cmeta", NULL);
	camel_object_set_state_filename (CAMEL_OBJECT (folder), state_file);
	g_free (state_file);
	camel_object_state_read (CAMEL_OBJECT (folder));

	ifolder->search = camel_folder_search_new ();
	ifolder->search_lock = g_mutex_new ();
	ifolder->stream_lock = g_mutex_new ();
	ifolder->ignore_recent = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
	ifolder->exists_on_server = 0;
	ifolder->unread_on_server = 0;
	ifolder->modseq_on_server = 0;
	ifolder->uidnext_on_server = 0;

	if (!g_ascii_strcasecmp (folder_name, "INBOX")) {
		if (filter_inbox)
			folder->folder_flags |= CAMEL_FOLDER_FILTER_RECENT;
		if (filter_junk)
			folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;
	} else if (filter_junk && !filter_junk_inbox)
		folder->folder_flags |= CAMEL_FOLDER_FILTER_JUNK;

	camel_store_summary_connect_folder_summary (CAMEL_STORE_SUMMARY (CAMEL_IMAPX_STORE (store)->summary),
	                                            folder_name, folder->summary);

	return kfolder;
}

guint64
camel_kolab_imapx_folder_get_uidvalidity (CamelKolabIMAPXFolder *self,
                                          GError **err)
{
	CamelKolabIMAPXFolderClass *klass = NULL;
	CamelIMAPXExtdFolderClass *parent_class = NULL;
	guint64 uval = 0;

	g_return_val_if_fail (CAMEL_IS_KOLAB_IMAPX_FOLDER (self), 0);

	klass = CAMEL_KOLAB_IMAPX_FOLDER_GET_CLASS (self);
	parent_class = CAMEL_IMAPX_EXTD_FOLDER_CLASS (klass);

	/* TODO check whether we need offline capability here
	 */

	uval = parent_class->get_uidvalidity (CAMEL_IMAPX_EXTD_FOLDER (self),
	                                      err);

	return uval;
}

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