#ifndef __MQTT_UTILS_H__
#define __MQTT_UTILS_H__

#ifdef  __cplusplus
extern "C" {
#endif

#include <semaphore.h>

#include "MQTTAsync.h"
#include "MQTTClientPersistence.h"
#include "json_utils.h"

#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

#ifndef container_of
/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:	the pointer to the member.
 * @type:	the type of the container struct this is embedded in.
 * @member:	the name of the member within the struct.
 *
 */
#define container_of(ptr, type, member) ({			\
        const typeof(((type *)0)->member) * __mptr = (ptr);	\
        (type *)((char *)__mptr - offsetof(type, member)); })
#endif

typedef struct
{
	MQTTAsync client;
	MQTTAsync_responseOptions sub_opts;
	MQTTAsync_responseOptions pub_opts;

	sem_t sem_connect;			//mqtt connect semaphore

	/* MQTT options */
	enum MQTTASYNC_TRACE_LEVELS tracelevel;
	char host[64];		//mqtt broker ip
	int port;			//mqtt broker port
	char username[64];	//user name
	char password[64];	//user password
	int keepalive;		//mqtt keepalive
	int retain;			//mqtt retain
	char clientid[64];	//mqtt client id
	char productcode[64];	//mqtt productcode
	int MQTTVersion;

	/* will options */
	char* will_topic;
	char* will_payload;
	int will_qos;
	int will_retain;

	/* TLS options */
	char protocol[64];	//tcp ssl wss
	int insecure;
	char* capath;
	char* cert;
	char* cafile;
	char* key;
	char* keypass;
	char* ciphers;
}mqtt_utils_t;

extern mqtt_utils_t mqtt_config;
extern void PutDataIntoMQueue(char *payload);

typedef struct{
    char msg_messageId[32];
    char msg_fwVersion[32];
    char msg_fwUrl[256];
    int msg_taskId;
}mqtt_parm_download_t;

typedef struct
{
    char msg_deviceId[32];
    char msg_messageId[32];
    char msg_type[32];
    char msg_zipPath[512];
    char msg_version[32];
    char msg_scene[32];
    char msg_timeout[32];
    char msg_label1[32];
    char msg_label2[32];
    char msg_label3[32];
    char msg_label1Rule[32];
    char msg_label2Rule[32];
    char msg_label3Rule[32];
    char msg_color[32];
    char msg_sound[32];
    char msg_flash[32];
    char msg_flashInterval[32];
    char msg_lightDuration[32];
    char msg_sn[32];
    char msg_lights[128];
    int msg_needWifi;
    int msg_installType;
    int msg_immediately;
    int msg_installTime;
    int msg_timestamp;
    int msg_opNumber;
}mqtt_parm_t;

typedef struct
{
    char cabinetName[2];
    char cellName[32];
    char cellState[32];
    char cellVoltageType[32];
    char cellConnectorType[32];
    char cellRepairType[64];
    char devType[32];
    char devCheckType[32];
    char devSn[64];
    char devPvd[32];
    char devPro[64];
    char devMfg[64];
    char devState[32];
    char devRepairType[512];
    char batchId[64];
    char opType[64];
    char opTime[64];
    int devPwr;
    int userId;
}db_parm_t;

typedef struct{
    char result[1024];
    char opTime[32];
    char opType[32];
    char status[32];
    int userId;
}test_parm_t;

extern void mqtt_net_failure(int *failure_times);
extern int mqtt_utils_init(mqtt_utils_t *mqtt_utils);
extern int get_trace_level_by_name(char *name);
extern int mqtt_utils_subscribe(mqtt_utils_t *mqtt_utils, char *topic, int qos);
extern int mqtt_utils_publish(mqtt_utils_t *mqtt_utils, char *topic, int qos, const char *data,  int datalen);
extern int mqtt_utils_uninit(mqtt_utils_t *mqtt_utils);
void mqtt_service_invoke_reply(char *msg_id, char *code, char *status, char *msg_type, char *json_name, struct json_object *json_val);
void mqtt_service_cell_report(char *cellName,db_parm_t *db_parm);
void mqtt_service_returndev_event_report(char *cellName,db_parm_t *db_parm);
void mqtt_service_losedev_event_report(char *cellName,db_parm_t *db_parm);
void mqtt_service_borrowdev_event_report(char *cellName,db_parm_t *db_parm);
void mqtt_service_managedev_event_report(test_parm_t *test_parm,char *eventType);
void mqtt_service_uploadlog_report(char *filename,char *fileurl,char *msg_id);
void mqtt_service_downloadapp_report(char *msg_id,int task_id,char *code,char *message);
void mqtt_service_softversion_report(char *fwversion);
void mqtt_handle_error_event_report(char *cellname,char *batchid,char *optime,int userid,char *opType);
void mqtt_server_station_status_report(char *msg_id,char *product_id,char *sn,char *local_ip, char *base_version,
                                       char *status, char *duration);
void mqtt_service_reply(char *sn,char *msg_id,char *msg,int success,char *product_id);
void mqtt_resource_reply(char *sn,char *msg_id,char *msg,int success,char *product_id, char *resource);
void mqtt_server_light_status_report(char *sn,char *msg_id,char *scene,json_object *lights);
void mqtt_server_light_status_report_test(char *sn,char *msg_id,char *scene,json_object *lights);
void mqtt_server_light_status_report_2(char *sn,char *msg_id,char *scene,json_object *lights);
void mqtt_server_station_status_report_test(char *msg_id,char *product_id,char *sn,char *local_ip, char *base_version,
                                       char *status, char *duration);
#ifdef  __cplusplus
}
#endif

#endif
