#ifndef __DAS_LINK_H__
#define __DAS_LINK_H__
    #include <stdint.h>
    #include "cjson/cJSON.h"

    #define DAS_LINK_SDK_VERSION "v1.2.1"

    #ifndef RET_SUCCESS
    #define RET_SUCCESS  (0)
    #endif

    #ifndef RET_FAILURE  
    #define RET_FAILURE  (-1)
    #endif

    #define FIRMWARE_VERSION_MAX (16)

    typedef enum {
        DAS_LINK_NOTICE_DISCONNECT,  // notice disconnect
        DAS_LINK_NOTICE_CONNECT,     // notice connect
    } daslink_notice_t;

    typedef enum {
        METHOD_MODE_OTA,
        METHOD_MODE_PROPERTY,
        METHOD_MODE_CUSTOM
    } method_mode_t;

    typedef struct {
        uint8_t         dup;
        uint16_t        topic_len;
        uint32_t        payload_len;
        const char     *ptopic;
        const char     *payload;
    } daslink_topic_info_t;

    /*
     *  @brief declare callback function for notice 
     */
    typedef void (*daslink_notice_proc_t)(daslink_notice_t type, const void *user_args);

    /**
     * @brief  specify the topic callback function 
     */
    typedef void (*daslink_sub_topic_func_t)(const void *user_args, daslink_topic_info_t *info);

    /**      
     *  @brief declare callback function for method, daslink will call the method 
     *   when cloud request with the method
     *  @return None
     *  @example:
     *   in format : {"enable": 1, "cpuUsage": 15, "ramUsage": 60}
     */
    typedef void (*daslink_method_proc_t)(const char *msg_id, const cJSON *in,  const void *user_args);

    typedef struct{
        char *thing_id;                     // thing id
        char *device_id;                    // device id
        char *device_secret;                // device secret
        char *host;                         // mqtt broker addr
        uint16_t   port;                    // mqtt broker port

        char firmware_ver[FIRMWARE_VERSION_MAX + 1]; // firmware version, the param is required if enabled ota
        cJSON *extra_obj;                   // extra info to report cloud when sdk connected
        char *sec_path;                     // enter path of secheart if daslink
                                            //support secheart, or NULL
    } daslink_params_info_t;

    /**
     * @brief daslink 的初始化
     * 
     * @param params daslink 初始化需要的参数
     * @param func daslink 的callback通知接口， 用于通知应用层当前daslink的状态
     * @param user_args callback 的参数，用户自定义， 若无，则填写NULL
     * @return int 返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int  daslink_init(const daslink_params_info_t *params, daslink_notice_proc_t func, const void *user_args);

    /**
     * @brief daslink 的资源释放
     */
    void daslink_deinit(void);

    /**
     * @brief daslink 属性数据上报
     * 
     * @param property_name 属性名 
     * @param property_obj 数据对象，类型可有cJSON自行定义
     * @return int 返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int  daslink_report_property(const char *property_name, const cJSON *property_obj);

    /**
     * @brief daslink 事件数据上报
     * 
     * @param event_name 事件名
     * @param event_obj 事件对象， 类型为cJSON Object
     * @return int 返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int  daslink_report_event(const char *event_name, const cJSON *event_obj);

    /**
     * @brief daslink 服务的注册
     * 
     * @param method_name 服务名
     * @param cb 处理服务的回掉接口
     * @param userArgs 用户自定义的参数，若不需要，则填写NULL
     * @return int  返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int  daslink_register_method(const char *method_name, daslink_method_proc_t cb, const void *userArgs);

    /**
     * @brief daslink 服务的注销
     * 
     * @param method_name 服务名
     * @return int 返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int  daslink_unregister_method(const char *method_name);

    /**
     * @brief daslink 服务的响应接口， 即在daslink_method_proc_t 定义的函数中，用该接口进行响应
     * 
     * @param method_name 服务名
     * @param msg_id 消息Id， 该参数由daslink_method_proc_t 定义定义的msg_id 对应
     * @param out 响应的消息体，数据类型由cJSON自行定义
     * @return int 返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int daslink_method_response(const char *method_name, const char *msg_id, const cJSON *out);


    /**
     * @brief daslink 自定义发布消息
     * 
     * @param topic 主题名
     * @param qos 消息质量
     * @param data 发布的消息内容
     * @param len  发布消息的长度
     * @return int 返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int daslink_pub(const char *topic, int qos, void *data, int len);

    /**
     * @brief daslink  自定义订阅消息
     * 
     * @param topic_filter 主题名
     * @param qos 消息质量
     * @param topic_func 处理订阅内容的回掉接口， 当由该主题的消息时，会触发该回掉接口
     * @param user_args 自定义参数，回掉接口被调用时，会携带该参数
     * @param timeout_ms 订阅超时时间
     * @return int 返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int daslink_sub(const char *topic_filter, int qos, daslink_sub_topic_func_t topic_func,
                    const void *user_args, int timeout_ms);

    /**
     * @brief daslink 取消订阅的消息
     * 
     * @param topic_filter 主题名
     * @return int 返回值，成功： RET_SUCCESS， 失败：RET_FAILURE
     */
    int daslink_unsub(const char *topic_filter);


    int daslink_enable_ota(daslink_method_proc_t cb, const void *userArgs);

#endif
