#ifndef _ANTISPAM_PLUGIN_H
#define _ANTISPAM_PLUGIN_H

#include "lib.h"
#include "str.h"
#include "imap-client.h"
#include "ostream.h"
#include "imap-search.h"
#include <stdlib.h>

#include "antispam-settings.h"

#define __stringify_1(x)	#x
#define stringify(x)		__stringify_1(x)

#define __PLUGIN_FUNCTION(name, ioe) \
	name ## _plugin_ ## ioe
#define _PLUGIN_FUNCTION(name, ioe) \
	__PLUGIN_FUNCTION(name, ioe)
#define PLUGIN_FUNCTION(ioe)	\
	_PLUGIN_FUNCTION(antispam, ioe)

struct antispam_transaction_context;

enum classification {
	CLASS_NOTSPAM,
	CLASS_SPAM,
};

struct backend {
	bool (*settings)(struct antispam_settings *set, pool_t pool,
			 const char **error_r);
	/*
	 * Handle mail; parameters are
	 *  - t: transaction context
	 *  - ast: transaction context from backend_start()
	 *  - mail: the message
	 *  - wanted: the wanted classification determined by the user
	 */
	int (*handle_mail)(const struct antispam_settings *cfg,
			   struct mailbox_transaction_context *t,
			   struct antispam_transaction_context *ast,
			   struct mail *mail, enum classification wanted);
	struct antispam_transaction_context *(*start)(const struct antispam_settings *cfg,
						      struct mailbox *box);
	void (*rollback)(const struct antispam_settings *cfg,
			 struct antispam_transaction_context *ast);
	int (*commit)(const struct antispam_settings *cfg,
		      struct mailbox_transaction_context *ctx,
		      struct antispam_transaction_context *ast);
};

static inline const char *const *
get_mail_headers(struct mail *mail, const char *hdr)
{
	const char *const *ret;

	if (mail_get_headers(mail, hdr, &ret) < 0)
		return NULL;
	return ret;
}

/* signature handling */
struct siglist {
	struct siglist *next;
	char *sig;
	enum classification wanted;
};

int signature_extract_to_list(const struct antispam_settings *cfg,
			      struct mailbox_transaction_context *t,
			      struct mail *mail, struct siglist **list,
			      enum classification wanted);
int signature_extract(const struct antispam_settings *cfg,
		      struct mailbox_transaction_context *t,
		      struct mail *mail, const char **signature);
void signature_list_free(struct siglist **list);


/* possible backends */
extern struct backend crm114_backend;
extern struct backend dspam_backend;
extern struct backend pipe_backend;
extern struct backend spool2dir_backend;

void debug(const struct antispam_settings *cfg,
	   const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
void debugv(const struct antispam_settings *cfg, char **args);
void debugv_not_stderr(const struct antispam_settings *cfg, char **args);
void debug_verbose(const struct antispam_settings *cfg,
		   const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));

bool mailbox_is_spam(const struct antispam_settings *cfg, struct mailbox *box);
bool mailbox_is_trash(const struct antispam_settings *cfg, struct mailbox *box);
bool mailbox_is_unsure(const struct antispam_settings *cfg, struct mailbox *box);
bool keyword_is_spam(const struct antispam_settings *cfg, const char *keyword);

struct antispam_settings *antispam_setup_config(void);
void antispam_free_config(struct antispam_settings *cfg);

void antispam_storage_init(struct module *module);
void antispam_storage_deinit(void);

void lowercase_string(const char *in, char *out);

extern const struct setting_parser_info antispam_setting_parser_info;

#endif /* _ANTISPAM_PLUGIN_H */
