#ifndef __KK_DM_MNG__
#define __KK_DM_MNG__
#include "com_api.h"
#include "kk_tsl_common.h"
#include "klist.h"

#include "iotx_dm.h"

#define KK_DM_DEVICE_CCU  (0x01)
#define KK_DM_DEVICE_SUBDEV  (0x02)
#define KK_DM_DEVICE_GATEWAY (0x04)
#define KK_MID_SYNC_DEFAULT_TIMEOUT_MS (200)
#define IDENTIFY_MAXLEN      (64 + 1)
#define KK_DM_CCU_DEVICE_PRODUCT_TYPE "ccu"
#define KK_DM_CCU_DEVICE_PRODUCT_CODE  KK_CCU_PRODUCTID
#define KK_DM_GW_DEVICE_PRODUCT_TYPE "gw"
#define KK_DM_GW_DEVICE_PRODUCT_CODE "2"
#define KK_DM_AIR_GATEWAY_TYPE "air conditioning gateway"
#define KK_DM_DEVICE_CCU_DEVICEID  (0x00)
#define MSG_MAX_LEN                 (64)

typedef struct {
	int devid;
    int dev_type;
    kk_tsl_t *dev_shadow;
    char mac[DEVICE_MAC_MAXLEN];
    char productCode[PRODUCT_CODE_MAXLEN];
	char deviceCode[DEVICE_CODE_MAXLEN];
	char fatherDeviceCode[DEVICE_CODE_MAXLEN];
	char productType[PRODUCT_TYPE_MAXLEN];	
	char isOffline;
	int hb_timeout; //heartbeat time
	time_t timestamp;
	char dormancyDev; //1，休眠设备；0，不是
	struct list_head linked_list;
} dm_mgr_dev_node_t;

typedef struct {
	void *mutex;
	int global_devid;
	struct list_head dev_list;
} dm_mgr_ctx;

typedef struct kk_dm_property_handle
{
	char property[DEVICE_PROPERTY_NAME_MAX];
	union{
		char *valueStr;
		double value;
	};
	int type;

}kk_dm_property_handle_t;

typedef struct kk_dm_property_e
{
	kk_dm_property_handle_t info[DEVICE_PROPERTY_NUM_MAX];
	int num;
}kk_dm_property_e_t;

typedef struct {
	char msgid[MSG_MAX_LEN];
	int devid;
    //const char *service_prefix;
    //const char *service_name;
	char *msgTypeStr;
	char identity[IDENTIFY_MAXLEN];	
	char productCode[PRODUCT_CODE_MAXLEN];
	char deviceCode[DEVICE_CODE_MAXLEN];
	char *params;
	int params_len;
	char *method;
	//iotx_cm_data_handle_cb callback;
} dm_msg_request_t;
typedef struct {
	char *msgTypeStr;
    char productCode[PRODUCT_CODE_MAXLEN];
    char deviceCode[DEVICE_CODE_MAXLEN];

	iotx_dm_error_code_t code;
} kk_msg_response_t;
int dm_mgr_search_dev_by_devid(_IN_ int devid, _OU_ dm_mgr_dev_node_t **node);
int dm_mgr_properities_db_create(kk_tsl_t* dev_shadow,char *deviceCode,int devType );
int dm_mgr_get_device_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_mgr_dev_node_t **node);
int dm_mgr_device_create(_IN_ int dev_type,_IN_ char productCode[PRODUCT_CODE_MAXLEN], _IN_ char deviceCode[DEVICE_CODE_MAXLEN],
			_IN_ char mac[DEVICE_MAC_MAXLEN],_IN_ char fatherDeviceCode[DEVICE_CODE_MAXLEN],_IN_ int isOffline, _OU_ int *devid,_OU_ int *heartbeat);
int dm_mgr_search_device_by_pkdn( _IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ int *devid);
int dm_mgr_get_devicetype_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ int* deviceType);
int dm_mgr_get_device_shadow_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ kk_tsl_t **shadow);
int dm_mgr_get_device_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN], _OU_ dm_mgr_dev_node_t **node);
int dm_mgr_get_deviceNum_by_productType(_IN_ char *productType);
int dm_mgr_update_timestamp_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],time_t timestamp);
int dm_mgr_set_dev_onoffline(dm_mgr_dev_node_t *node,int isOffline);
int dm_mgr_check_heartbeat_timeout(time_t timestamp);
int dm_mgr_get_devId_by_devicecode(_IN_ char deviceCode[DEVICE_CODE_MAXLEN],_OU_ int *devid);
int dm_mgr_init(void);
int dm_mgr_deinit(void);
int iotx_report_id(char *msgId);
int dm_mgr_upstream_thing_property_post(_IN_ int devid, _IN_ char *payload, _IN_ int payload_len,_IN_ int isAsync);
int dm_mgr_upstream_thing_event_post(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *method,
                                     _IN_ char *payload, _IN_ int payload_len);
int dm_mgr_upstream_thing_event_post_ex(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *method,
								  _IN_ char *payload, _IN_ int payload_len,const char *msgId);
int dm_mgr_upstream_thing_service_post(_IN_ int devid, _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *method,
                                     _IN_ char *payload, _IN_ int payload_len);
int dm_mgr_deprecated_upstream_thing_service_response(_IN_ int devid, _IN_ int msgid, _IN_ iotx_dm_error_code_t code,
        _IN_ char *identifier, _IN_ int identifier_len, _IN_ char *payload, _IN_ int payload_len);
int dm_mgr_upstream_thing_sub_register(_IN_ int devid);
int dm_mgr_upstream_thing_sub_unregister(_IN_ int devid);
int dm_mgr_upstream_thing_topo_add(_IN_ int devid);
int dm_mgr_upstream_thing_topo_delete(_IN_ int devid);
int dm_mgr_upstream_thing_topo_get(void);
int dm_mgr_upstream_thing_list_found(_IN_ int devid);
int dm_mgr_ccu_status_cloud(_IN_ int devid);
int dm_mgr_upstream_status_online(_IN_ int devid);
int dm_mgr_upstream_status_offline(_IN_ int devid);
int dm_mgr_upstream_combine_login(_IN_ int devid);
int dm_mgr_upstream_combine_logout(_IN_ int devid);
int dm_mgr_ota_report_version(_IN_ int devid, char *version);
int dm_mgr_subdev_create(int devtype,_IN_ char productCode[PRODUCT_CODE_MAXLEN], _IN_ char deviceCode[DEVICE_CODE_MAXLEN],
		_IN_ char mac[DEVICE_MAC_MAXLEN],_IN_ char fatherDeviceCode[DEVICE_CODE_MAXLEN],_IN_ int isOffline, _OU_ int *devid,_OU_ int *heartbeat);
int dm_mgr_subdev_delete(_IN_ char deviceCode[DEVICE_CODE_MAXLEN]);     
int dm_msg_thing_property_post_all(char *deviceCode);   
int dm_mgr_get_gw_deviceCode(_OU_ dm_mgr_dev_node_t **node);                              
#endif
