#ifndef IPC_SESSION_h
#define IPC_SESSION_h

#include "lnxall_list.h"

typedef struct _nng_session_s nng_session_t;
typedef struct _mqtt_session_s mqtt_session_t;

#define TOPIC_MAX_LEN 128

#ifndef MAX_CLIENT_ID_LEN
#define MAX_CLIENT_ID_LEN   128
#endif

/*
 * 底层通信方式
 * MQTT方式更加通用，但是效率低
 * NNG 高效
 */
typedef enum
{
    IPC_DEFAULT = 0,
    IPC_MQTT,
    IPC_NNG,
} ipc_mode_e;

typedef struct _ipc_msg_s
{
    struct list_head list;
    char *topic;    ///<发布、订阅主题
    int payloadLen; ///<发送内容长度
    char *payload;  ///<发布内容。如果是订阅消息该项可不填写
} ipc_msg_t;

typedef struct _ipc_session_s
{
    ipc_mode_e mode;
    union
    {
        nng_session_t *nng_session;
        mqtt_session_t *mqtt_session;
    } s;

    void *user_data;
} ipc_session_t;

/**
*******************************************************************************
*
* @brief  新建一个IPC会话
* @param id 会话ID
* @param user_data 用户数据，在回调中返回
* @param mode 会话通信模式
* @return NULL for fail
*
*******************************************************************************
*/
extern ipc_session_t *ipc_session_new(char *id, void *user_data, ipc_mode_e mode);

/**
*******************************************************************************
*
* @brief  订阅topic
* @param session IPC会话结构体的指针
* @param topic 要订阅的topic
* @return 0 for success; -1 for fail
*
*******************************************************************************
*/
extern int ipc_session_subscribe(ipc_session_t *session, const char *topic);

/**
*******************************************************************************
*
* @brief  设置IPC会话的回调函数
* @param session IPC会话结构体的指针
* @param on_message 收到IPC消息时的回调函数，其中obj为new时传入的user_data
* @param on_state_change 目前只有MQTT消息有效
* @return 0 for success; -1 for fail
*
*******************************************************************************
*/
extern int ipc_session_set_callbacks(ipc_session_t *session, int (*on_message)(void *obj, ipc_msg_t *msg),
                                     int (*on_state_change)(void *obj, int state));

/**
*******************************************************************************
*
* @brief  设置IPC会话的选项
* @param session 会话结构体的指针
* @param qos 在发布消息时将采用此qos进行发布
* @param keepalive 连接的keepalive时间
* @return 0 for success; -1 for fail
*
*******************************************************************************
*/
extern int ipc_session_set_opts(ipc_session_t *session, int qos, int keepalive);

/**
*******************************************************************************
*
* @brief  设置会话的broker信息
* @param session MQTT 会话结构体的指针
* @param addr broker 地址
* @param port broker 端口
* @param user broker 连接用户名
* @param pass broker 连接密码
* @return 0 for success; -1 for fail
*
*******************************************************************************
*/
extern int ipc_session_set_address(ipc_session_t *session, char *addr, unsigned short port, char *user, char *pass);


/**
*******************************************************************************
*
* @brief 发布IPC消息
* @param session IPC会话结构体的指针
* @param topic 消息topic
* @param payload 消息体
* @param payloadlen 消息长度
* @return 0 for success
*
*******************************************************************************
*/
extern int ipc_session_publish(ipc_session_t *session, char *topic, const void * payload, int payloadlen);

/**
*******************************************************************************
*
* @brief  启动IPC会话
* @param session IPC会话结构体的指针
* @return 0 for success; -1 for fail
*
*******************************************************************************
*/
extern int ipc_session_start(ipc_session_t *session);

/**
*******************************************************************************
*
* @brief 销毁IPC session
* @param session IPC会话结构体的指针
* @return 0 for success
*
*******************************************************************************
*/
extern int ipc_session_destroy_and_free(ipc_session_t *session);

#endif
