#ifndef SIEVE_MATCH_H
#define SIEVE_MATCH_H

#include "sieve-common.h"

/*
 * Matching context
 */

struct sieve_match_context {
	pool_t pool;

	const struct sieve_runtime_env *runenv;

	const struct sieve_match_type *match_type;
	const struct sieve_comparator *comparator;

	void *data;

	int match_status;
	int exec_status;

	bool trace:1;
};

/*
 * Matching implementation
 */

/* Manual value iteration (for when multiple matches are allowed) */
struct sieve_match_context *sieve_match_begin
	(const struct sieve_runtime_env *renv,
		const struct sieve_match_type *mcht,
		const struct sieve_comparator *cmp);
int sieve_match_value
	(struct sieve_match_context *mctx, const char *value, size_t value_size,
		struct sieve_stringlist *key_list);
int sieve_match_end(struct sieve_match_context **mctx, int *exec_status);

/* Default matching operation */
int sieve_match
	(const struct sieve_runtime_env *renv,
		const struct sieve_match_type *mcht,
		const struct sieve_comparator *cmp,
		struct sieve_stringlist *value_list,
		struct sieve_stringlist *key_list,
		int *exec_status);

/*
 * Read matching operands
 */

enum sieve_match_opt_operand {
	SIEVE_MATCH_OPT_END,
	SIEVE_MATCH_OPT_COMPARATOR,
	SIEVE_MATCH_OPT_MATCH_TYPE,
	SIEVE_MATCH_OPT_LAST
};

int sieve_match_opr_optional_dump
	(const struct sieve_dumptime_env *denv, sieve_size_t *address, int *opt_code);

int sieve_match_opr_optional_read
	(const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code,
		int *exec_status, struct sieve_comparator *cmp,
		struct sieve_match_type *mcht);

#endif
