/* imap.h - header file for asynchronous streaming imap command routines 
 *
 * (C) 2001 by Harald Welte <laforge@gnumonks.org>
 *
 * $Id: imap.h,v 1.4 2001/03/29 22:08:25 laforge Exp $
 */
#ifndef _IMAP_H
#define _IMAP_H

#include "list.h"
#include "message.h"

typedef struct buffer_s {
	int size;
	int offset;		/* offset for new data */
	int parse;		/* we've parsed response up to here */
	char buf[0];
} buf_t;

/* how much space is in buf left */
#define buf_space(x) (x->size - x->offset - 1)

/* the pointer to the first byte where to store more data */
#define buf_cur(x) (x->buf + x->offset)

/* pointer to byte where to start parsing */
#define buf_parse(x) ((char *) (x->buf + x->parse))

#define buf_end(x) (x->buf + x->size)

/* how many bytes still to parse */
#define buf_parse_len(x) (buf->offset - buf->parse - 1)

/* allocate a buffer */
buf_t *buf_alloc(int size);

/* free a buffer */
void buf_free(buf_t * buf);

/* enlarge a buffer */
buf_t *buf_enlarge(buf_t * buf, u_int32_t by);

#define IMAP_CMD_MAXSIZE	255	/* maximum lenght of one imap cmd */

#if 0
#define	IMAP_DEBUGP(x, args...) fprintf(stderr, x, ## args)
#else
#define IMAP_DEBUGP(x, args...)
#endif

typedef struct imap_cmd_s imap_cmd_t;
typedef struct imap_s imap_t;
/* structure representing one command */
struct imap_cmd_s {
	imap_cmd_t *next;
	char command[IMAP_CMD_MAXSIZE];
	u_int32_t tag;
	int (*callback) (buf_t * buf, imap_cmd_t * cmd);
	union {
		/* put in per-command specific private data here */

		void *param;

		struct {
			char *mbox_path;	/* path of the directory */
			int flags;		/* flags of this message */
			unsigned int uid;	/* unique ID of this message */
		} fetch;

	} private;
	imap_t *imap;		/* pointer to imap handle */
};

/* imap connection handle */
struct imap_s {
	unsigned int count;	/* # of msgs */
	unsigned int recent;	/* # of recent messages */
	message_t *msgs;	/* list of messages on the server */
	unsigned int deleted;	/* # of deleted messages */
	unsigned int uidvalidity;
	unsigned int maxuid;
	unsigned int minuid;
	/* NAMESPACE info */
	list_t *ns_personal;
	list_t *ns_other;
	list_t *ns_shared;
	unsigned int have_namespace:1;
	unsigned int have_cram:1;
	unsigned int have_starttls:1;
	unsigned int cram:1;

	imap_cmd_t *command_queue;	/* queue of pending commands */
	imap_cmd_t *active_queue;	/* queue of currently executing commands */

	unsigned long sender_tag;	/* currend IMAP tag of the sender */
	int receiver_lastline;		/* is receiver in last line ? */
	unsigned int receiver_tag;	/* current IMAP tag of the receiver */
	unsigned int receiver_skip;	/* we want to skip n bytes */
};

/* dequeue one command, return pointer to null-terminated buffer */
int imap_sender(imap_t * imap, char *buf);

/* call this routing as soon as there's something to read */
int imap_receiver(imap_t * imap, buf_t * buf);

imap_cmd_t *imap_cmd_alloc(void);
void imap_cmd_free(imap_cmd_t * cmd);

/* enqueue an imap command*/
int imap_enqueue_command(imap_t * imap, imap_cmd_t * cmd);

/* query if there are commands pending */
int imap_commands_pending(imap_t * imap);

/* query if we are still waiting for replies */
int imap_replies_pending(imap_t * imap);

#endif				/* _IMAP_H */
