#ifndef __SERVICE_STRUCT_INCLUDE_H__
#define __SERVICE_STRUCT_INCLUDE_H__

#include "lib_acl.h"
#include "conn_cache.h"
#include "dns.h"

#include <time.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct SERVICE SERVICE;
typedef struct CLIENT_ENTRY CLIENT_ENTRY;

/* ̬غͶ */

/* ʼͶ */
typedef void (*module_service_init_fn)(ACL_DLL_ENV *dll_env, const char *cfgdir);
/* 񴴽Ͷ */
typedef SERVICE *(*module_service_create_fn)(void);
/* ںͶ */
typedef void (*module_service_main_fn)(SERVICE *service, ACL_ASTREAM *stream);

typedef struct {
	module_service_init_fn mod_init;
	module_service_create_fn mod_create;
	module_service_main_fn mod_main;
} MODULE_SERVICE;

struct SERVICE {
	char  name[256];			/*  */
	ACL_AIO *aio;				/* 첽IO */
	acl_pthread_pool_t *wq;			/* Ϊ˼ϵģҪ̳߳ؾ */
	ACL_ASTREAM *sstream;			/* ׽ӿ */
	int   conn_timeout;			/* Ĭϵӳʱʱ */
	int   rw_timeout;			/* ĬϵIOʱʱ */
	ACL_DNS *dns_handle;			/* ֱӷDNSЭ鷽ʽѯ */
	DNS_SERVER *dns_server;			/* DNSѯ */
	ACL_HTABLE *dns_table;			/* DNSѯϣ */
	char  local_addr[256];			/* ıصַ */
	char **bind_ip_list;			/* ӷʱ󶨱IPַб */
	int   bind_ip_index;			/* ǰҪ󶨵IP */

	CONN_CACHE *conn_cache;			/* ӳض */
	MODULE_SERVICE *module;			/* ķģ */
};

typedef struct DNS_RING {
	char  domain_key[256];
	ACL_RING ring;
	int   nrefer;
} DNS_RING;

struct CLIENT_ENTRY {
	SERVICE *service;			/* ָ첽 */
	ACL_ASTREAM *client;			/* ڿͻ˵ */
	ACL_ASTREAM *server;			/* ˵ */

	int   nrefer;				/* ü */

	ACL_RING dns_entry;			/* DNSѯĳ */
	char  domain_key[256];			/* (Сд) */
	char  domain_addr[64];			/* ӦһIPַ */

	DNS_CTX dns_ctx;			/* صĵַϢ */
	int   ip_idx;				/* ǰõIPַ */
	int   ip_ntry;				/*  IP  */
	int   server_port;			/* PORT */
	char  client_ip[32];			/* ͻIPַ */
	int   client_port;			/* PORT */
	const char *dns_errmsg;

	struct {
		time_t begin;			/* Ựʼʱ */
		time_t stamp;			/* ̬ıʱ */

		time_t dns_lookup;		/* DNSѯʱ(Ϊλ) */
		time_t connect;			/* ӷʱ(Ϊλ) */
	} tm;

	int   flag_has_replied;

	int   flag_conn_reuse;			/* ظӳе */
	int   nretry_on_error;			/* Դ */
#define MAX_RETRIED	10

	void (*free_fn)(CLIENT_ENTRY*);
	void (*nslookup_notify_fn)(CLIENT_ENTRY*, int);
#define	NSLOOKUP_OK	0
#define	NSLOOKUP_ERR	-1

	int  (*connect_notify_fn)(CLIENT_ENTRY*);
	void (*connect_timeout_fn)(CLIENT_ENTRY*);
	void (*connect_error_fn)(CLIENT_ENTRY*);
};

#ifdef __cplusplus
}
#endif

#endif
