/* Copyright (C) 2012 Timo Sirainen, LGPLv2.1 */

/*
   eval `cat /usr/local/lib/dovecot/dovecot-config`
   gcc -fPIC -shared -DHAVE_CONFIG_H \
     `echo $DOVECOT_CFLAGS $LIBDOVECOT_INCLUDE $LIBDOVECOT_STORAGE_INCLUDE` \
     mailbox-alias-plugin.c -o mailbox_alias_plugin.so
*/

#include "lib.h"
#include "module-context.h"
#include "mailbox-list-private.h"
#include "mail-storage-hooks.h"

#define MAILBOX_ALIAS_LIST_CONTEXT(obj) \
	MODULE_CONTEXT(obj, mailbox_alias_mailbox_list_module)

struct mailbox_alias_mailbox_list {
	union mailbox_list_module_context module_ctx;
};

static MODULE_CONTEXT_DEFINE_INIT(mailbox_alias_mailbox_list_module,
				  &mailbox_list_module_register);

static struct {
	const char *vname;
	const char *storage_name;
} aliases[] = {
	{ "alias", "real" }
};

void mailbox_alias_plugin_init(struct module *module);
void mailbox_alias_plugin_deinit(void);

static const char *
mailbox_alias_get_vname(struct mailbox_list *list, const char *storage_name)
{
	struct mailbox_alias_mailbox_list *mlist =
		MAILBOX_ALIAS_LIST_CONTEXT(list);
	unsigned int i;

	for (i = 0; i < N_ELEMENTS(aliases); i++) {
		if (strcmp(aliases[i].storage_name, storage_name) == 0)
			return aliases[i].vname;
	}

	return mlist->module_ctx.super.get_vname(list, storage_name);
}

static const char *
mailbox_alias_get_storage_name(struct mailbox_list *list, const char *vname)
{
	struct mailbox_alias_mailbox_list *mlist =
		MAILBOX_ALIAS_LIST_CONTEXT(list);
	unsigned int i;

	for (i = 0; i < N_ELEMENTS(aliases); i++) {
		if (strcmp(aliases[i].vname, vname) == 0)
			return aliases[i].storage_name;
	}

	return mlist->module_ctx.super.get_storage_name(list, vname);
}

static void mailbox_alias_mailbox_list_created(struct mailbox_list *list)
{
	struct mailbox_alias_mailbox_list *mlist;
	struct mailbox_list_vfuncs *v = list->vlast;

	mlist = p_new(list->pool, struct mailbox_alias_mailbox_list, 1);
	mlist->module_ctx.super = *v;
	list->vlast = &mlist->module_ctx.super;
	v->get_vname = mailbox_alias_get_vname;
	v->get_storage_name = mailbox_alias_get_storage_name;
	MODULE_CONTEXT_SET(list, mailbox_alias_mailbox_list_module, mlist);
}

static struct mail_storage_hooks mailbox_alias_mail_storage_hooks = {
	.mailbox_list_created = mailbox_alias_mailbox_list_created
};

void mailbox_alias_plugin_init(struct module *module ATTR_UNUSED)
{
	mail_storage_hooks_add(module, &mailbox_alias_mail_storage_hooks);
}

void mailbox_alias_plugin_deinit(void)
{
	mail_storage_hooks_remove(&mailbox_alias_mail_storage_hooks);
}
