#ifndef __DR_COMMON_H
#define __DR_COMMON_H

/***************HEADER FILES****************/
#include <string.h>
#include <syslog.h>
#include "ipc_session.h"
#include "lnxall_list.h"
#include "dy_utils/dy_common.h"
#include "dy_utils/dy_pp.h"
#include "dy_utils/dy_db.h"
#include "dy_utils/dy_ipc.h"
#include "sqlite3.h"
/******************************************/

#define PERIOD_TIMER_INTERVAL     (60 *60 * 1000)     ///周期上报检查时间间隔
#define HASH_SIZE              16

static inline int hash_string(const char* s)
{
    unsigned long h = 0;
    for ( ; *s; ++s)
        h = 5 * h + *s;
    return h & (HASH_SIZE -1);
}

typedef struct
{
    struct list_head list;
    tag_table_t tag;
    object_property_table_t *poutput;///<位号指针数组
}rtd_data_list_t;

typedef struct
{
    struct hlist_node list;
    char identifier[64];
    time_t last_report; ///<上次上报时间
} identifier_node_t;


typedef struct
{
    struct hlist_node list;
    char dev_sn[SN_MAX_LEN];
    struct hlist_head identifier_table[HASH_SIZE];
} dev_sn_node_t;

typedef struct
{
    int period_report;
	int hourly_report;
	time_t last_check;
} period_property_info_t;

typedef struct _dr_var_s
{
    ipc_session_t* session; //内部broker的MQTT session，用于进程间通信
    nodes_cfg_table_t *nodes_cfg_table; //节点信息
    object_table_t *object_table; //物模型信息
    dy_db_session_t *db_session; //用于操作DB的会话
    int report_timer; //周期上报用的timer
    int period_property_timer; //周期属性上报用的timer
	int condition_cnt;
	struct list_head condition_list;
    char sn_str[SN_MAX_LEN];
    char proc_name[PROGRAM_NAME_LEN];
    struct hlist_head dev_sn_table[HASH_SIZE];
	period_property_info_t period_property_info;
} dr_var_t;

#define MAX_DC_NUM	10
#define DR_DC_CFG_FILE "/app/config/dc.json"
#define DR_DC_DB_FILE	"/app/dr_dc_data.db"
#define DR_DC_DB_TMPFS_NAME "/tmp/dr_dc_data.db"


/******************************************************************************
	+─────────────+──────────+───────────────────────────────+
	| 字段名       | 类型     | 描述                          |
	+─────────────+──────────+───────────────────────────────+
	| id          | INTEGER  | 索引                          |
	+─────────────+──────────+───────────────────────────────+
	| sn          | TEXT     | 设备序列号                     |
	+─────────────+──────────+───────────────────────────────+
	| tag         | BLOB     | 数据内容，可以是json字符串或二进制数据|
	+─────────────+──────────+───────────────────────────────+
	| time        | INTEGER  | 数据时间戳                     |
	+─────────────+──────────+───────────────────────────────+
	| identifier  | TEXT     | 服务名称  
	+─────────────+──────────+───────────────────────────────+
******************************************************************************/
#define DC_TAG_TABLE_CREATE \
    "id INTEGER PRIMARY KEY AUTOINCREMENT,"\
    "sn VARCHAR(64),"\
    "tag BLOB,"\
    "time INTEGER,"\
    "identifier VARCHAR(128)"

#define DC_DATA_TABLE_NAME "data"

#define DR_DC_INSERT_SQL "INSERT INTO "DC_DATA_TABLE_NAME" VALUES (NULL,?,?,?,?)"

#define DR_DC_GET_BETWEEN_TIME_WITH_SN_SQL "SELECT * FROM "DC_DATA_TABLE_NAME" WHERE sn IN (?) and time BETWEEN ? and ?"

#define DR_DC_GET_BETWEEN_TIME_WITHOUT_SN_SQL "SELECT * FROM "DC_DATA_TABLE_NAME" WHERE time BETWEEN ? and ?"

#define DR_DC_DELETE_DATA_SQL "DELETE FROM "DC_DATA_TABLE_NAME" WHERE time < ?"

#define DR_DC_PACK_DATABASE "VACUUM"

typedef struct _dr_var_dc_s_s
{
	//char sn_str[SN_MAX_LEN];
	char identifier[64];
	//char tag[64];
}dr_var_dc_s_t;

typedef struct _dr_var_dc_s
{
	sqlite3 *db; //db连接
	int limit_time;
	dr_var_dc_s_t var_dc_s[MAX_DC_NUM];
}dr_var_dc_t;

typedef struct _dr_dc_tag_s_s
{
	char sn[SN_MAX_LEN];
	char *tag_node;
	int tag_len;
	time_t time;
	char identifier[64];
	int id; 
}dr_dc_tag_table_t;


typedef struct
{
    struct list_head list;
    dr_dc_tag_table_t tag;
} dr_dc_tag_list_node_t;

#ifndef BOOL
#define BOOL unsigned char
#endif
#ifndef   FALSE
#define   FALSE   0
#endif
#ifndef   TRUE
#define   TRUE   1
#endif

extern dr_var_dc_t g_dr_var_dc_t;

extern int dr_handle_mqtt_data(dr_var_t *var, ipc_msg_t *mqtt_msg);
extern void *db_loop(void *param);
extern int dr_report_query_result(dr_var_t *var);
extern int db_tag_report_select_data(dr_var_t *var);
extern int dr_handle_period_property_report(dr_var_t *var);

extern int dr_dc_store_tag_to_db(sqlite3 *db, char * sn, char * identifier, char * data, time_t time);

extern int dr_dc_get_history_data(dr_var_t *var, ipc_msg_t *mqtt_msg);
time_t dr_uptime(time_t * tp);

#endif
