#ifndef CONFIG_H
#define CONFIG_H

#define GIMAP_LOGPATH	      "/big/GIX_IMAPD/logs"
#define GIMAP_RUNPATH	      "/big/GIX_IMAPD/run"
#define GIMAP_TMPPATH	      "/big/GIX_IMAPD/tmp"

#define GIMAP_CONFIG "/big/GIX_IMAPD/conf/gimapd.conf"
#define GIMAP_LOG_FILE      "/big/GIX_IMAPD/logs/gimapd.log"

#define GIMAP_MAX_SERVERS     16
#define GIMAP_MAX_CONNECTIONS 4096

#define IMAP_STATE_LOGGED_OUT 0
#define IMAP_STATE_LOGGED_IN  1
#define IMAP_STATE_SELECTED   2 // Only for IMAP state in a selected mailbox


#define GIMAP_VERSION "V1.0.3"

#define GIMAP_PREFIX "gimapd_homedir"

// #define GIMAP_CAP_RESPONSE "IMAP4REV1 AUTH=CRAM-MD5 AUTH=PLAIN"
#define GIMAP_CAP_RESPONSE "IMAP4REV1 UIDPLUS NAMESPACE I18NLEVEL=1 LITERAL+ AUTH=LOGIN AUTH=PLAIN"

#define GIMAP_DO_SELECT  1
#define GIMAP_DO_EXAMINE 0 
#define GIMAP_DO_REPARSE 2 

#define IMAP_MAX_LOCKS 16
#define IMAP_MAX_SUBSCRIBED 1024
#define IMAP_BLOCK_SIZE 1024


#define GIMAP_START_UID  ((u_int64_t)100)


struct gimap_supervisornet {
        u_int8_t prefixlen;
        u_int8_t family;
        u_int8_t address[32];
};




struct pop3_file {
	char filename[512];
	char mailbox[512];
	u_int64_t size;
	u_int64_t uidl; // Calculated from filename i%ld_000000 (Higher 32bit) and MAILBOX-UIDL (Lower 32bit)
	u_int8_t del;   // 0...not marked for deleting, 1...marked for deleting
	time_t modi;    // Modification-time (Used for sorting)
};

struct imap_flags { // For passing Flags between functions
	u_int8_t seen;
	u_int8_t recent; // May not be set by Client! 
	u_int8_t flagged;
	u_int8_t deleted;
	u_int8_t answered;
	u_int8_t draft;
	
};


struct imap_folder_list {
	char *boxname;
	u_int8_t hasinferiors;	
	u_int8_t noselect;
	u_int8_t haschildren;
	u_int8_t marked; // Means: Has recent messages since last select
};


struct imap_box_info {
	char name[1024];
	int total_messages;
	u_int64_t uid; // The UID of the box itself
	u_int64_t next_uid; // UID for next message
	int total;
	int seen;
	int unseen;
	int answered;
	int flagged;
	int deleted;
	int draft;
	int recent;
	int haschildren;
	int readonly; // 1...A readonly mailbox
	u_int64_t *uidlist;
};

#define IMAP_ARG_TYPE_NORMAL 0x00
#define IMAP_ARG_TYPE_BINARY 0x01


struct imap_connection {
	time_t created;
	int sock; // Only local!!!
	SSL *ssl; // Only local!!!
	SSL_CTX *ctx; // Only local!!!
	int ssl_started; 
	int addr_family;
	u_int8_t sockaddr_peer[128];
	int sockaddr_peer_len;
	u_int32_t bytes_in;
	u_int32_t bytes_out;
	int pid;

	// Global parameters
	u_int8_t is_supervisor;   // 0...logged in with normal user password, 1...logged in with supervisor
	u_int8_t username[128];
	// char mailbox[64]; 
	char homedir[256];
	int uid;
	int gid;
	u_int8_t state;           // Logged in or not (for both: POP3 and IMAP)
	struct mail_envelope *head; // The Headers of the actual message...used only within FETCH & SEARCH!!!  Loaded  in the Loop for the messages to FETCH, because it only takes around 0.030 ms
	struct mail_envelope *full; // The fully MIME-deparsed actual message...used only within FETCH & SEACH!!! Loaded on demand, because it takes around 1 ms...after usage should be set to 0!




	// POP3 specific session parameters
	struct  pop3_file *pop3_filelist; // A local pointer only...NOT in SHM
	int pop3_files;
	int pop3_files_undeleted;
	u_int64_t pop3_box_size;

	// IMAP specific parameters
	u_int8_t *imap_cmd;
	u_int8_t *imap_cmd_prefix;
	u_int8_t *imap_cmd_args;
	int imap_cmd_argc;
	u_int8_t **imap_cmd_argv;	
	u_int64_t *imap_cmd_arglen;
	u_int8_t *imap_cmd_argtype;
	struct imap_box_info *imap_current_box;
	FILE *boxlock[IMAP_MAX_LOCKS];
	char *boxlock_name[IMAP_MAX_LOCKS];
	char **subscription;
	time_t subscription_lastload;
	int subscriptions;
};

#define SERVER_KIND_IMAP_PLAIN   0
#define SERVER_KIND_IMAP_SSL     1
#define SERVER_KIND_POP3_PLAIN   2
#define SERVER_KIND_POP3_SSL     3

// Will be a shared memory
struct imap_config {
	unsigned short family; // AF_INET, AF_INET6, ...only informational
	unsigned short port; // The port...only informational
	u_int8_t sockaddr[128]; // Should be enough to keep binding-data
	int sockaddr_len;
	struct imap_connection connection[GIMAP_MAX_CONNECTIONS];	
	int connections;
	char ssl_key_file[512];
	char ssl_cert_file[512];
	char ssl_chain_file[512];
	char ssl_cipher_list[512];
	u_int8_t server_kind;
	int pid;
};


struct gimap_global_config {
	struct imap_config server[GIMAP_MAX_SERVERS];
	char hostname[512];
	int servers;
};

#define GIMAP_SHM_KEY 0xCABD1234


extern struct gimap_global_config *gc;
extern char *gimap_prefix;
extern int gimap_shm_id;
extern char *supervisor_crypt;

extern struct gimap_supervisornet *gi_supervisor;
extern int gi_supervisors;


#endif
