#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include "dy_utils/dy_common.h"
#include "vint_common.h"
#include "dy_utils/cJSON.h"

static int vint_external_cfg_parse(vint_var_t *var, const char *cfg_file)
{
    int m;
    int ret = -1;
    char *data = NULL;
    int size;
    FILE *pf = NULL;
    char *protocol_str;
    cJSON *root = NULL;

    pf = fopen(cfg_file, "r");
    if (pf == NULL)
    {
        return -1;
    }

    size = file_size2(cfg_file);
    data = malloc(size + 1);
    if (!data)
    {
        fclose(pf);
        dy_syslog(LOG_ERR, "[VINT] malloc faile, size:%d", size);
        return -1;
    }

    fread(data, sizeof(char), size, pf);
    fclose(pf);
    data[size] = 0;

    root = cJSON_Parse(data);
    if (root)
    {
        cJSON *cfgs = cJSON_GetObjectItem(root, "vports");
        for (m = 0; m < cJSON_GetArraySize(cfgs) ; m++)
        {
            cJSON *node = cJSON_GetArrayItem(cfgs, m);
            GET_JSON_VALUE_DY_STRING(node, "protocol", protocol_str);
            if (strcmp(protocol_str, "mqtt") == 0)
            {
                char	addr[MAX_HOST_LEN];		///<MQTT地址
                unsigned short port;            ///<MQTT端口
                char	user[MAX_USER_LEN];		///<MQTT
                char	pass[MAX_PASS_LEN];		///<MQTT地址

                GET_JSON_VALUE_STRING(node, "host", addr);
                GET_JSON_VALUE_INT(node, "port", port);
                GET_JSON_VALUE_STRING(node, "user", user);
                GET_JSON_VALUE_STRING(node, "passwd", pass);
                mqtt_session_set_address(var->session_ext, addr, port, user, pass);
            }
            else if (strcmp(protocol_str, "udp") == 0)
            {
                //GET_JSON_VALUE_INT(node, "port", var->udp_port);
            }
            else if (strcmp(protocol_str, "tcp") == 0)
            {
                //GET_JSON_VALUE_INT(node, "port", var->tcp_port);
            }
            else
            {
                dy_syslog(LOG_ERR, "[VINT] wrong protocol:%s", protocol_str);
                goto out;
            }
            free(protocol_str);
        }
    }

    ret = 0;
out:
    cJSON_Delete(root);
    free(data);
    return ret;
}

static void vint_ex_unsubscribe_all(vint_var_t *var)
{
    nodes_cfg_table_t *nodes = var->nodes_cfg_table; //节点信息
    node_cfg_t *node = NULL;
    mqtt_session_t *mqtt_session = var->session_ext;
    int i;

    dy_syslog(LOG_INFO, "subscribe all");
    if (nodes != NULL)
    {
        for (i = 0; i < nodes->node_cnt; i++)
        {
            node = &nodes->node[i];
            char topic[64] = {0};
            if (node->port == VINTF_MQTT)
            {
                snprintf(topic, sizeof(topic), "G/%s/#", node->sn);
                mqtt_session_subscribe(mqtt_session, topic);
                snprintf(topic, sizeof(topic), "D/%s/#", node->sn);
                mqtt_session_subscribe(mqtt_session, topic);
            }
            else if (node->port == VINTF_TCP)
            {
                // TCP的数据经由前置机到网关内部
                snprintf(topic, sizeof(topic), "F/%s/#", node->sn);
                mqtt_session_subscribe(mqtt_session, topic);
            }
        }
    }

    //前置机topic
    mqtt_session_subscribe(mqtt_session, "F/SearchSN");
}

static void vint_ex_subscribe_all(vint_var_t *var)
{
    nodes_cfg_table_t *nodes = var->nodes_cfg_table; //节点信息
    node_cfg_t *node = NULL;
    mqtt_session_t *mqtt_session = var->session_ext;
    int i;

    dy_syslog(LOG_INFO, "subscribe all");
    if (nodes != NULL)
    {
        for (i = 0; i < nodes->node_cnt; i++)
        {
            node = &nodes->node[i];
            char topic[64] = {0};
			
			if (strlen(node->app_key) && strcmp(node->app_key, "qSlisTS2f41N70hm") == 0)
            {
                snprintf(topic, sizeof(topic), "F/%s/#", node->device_id);
                mqtt_session_subscribe(mqtt_session, topic);
            }
            else if (node->port == VINTF_MQTT)
            {
                snprintf(topic, sizeof(topic), "G/%s/#", node->sn);
                mqtt_session_subscribe(mqtt_session, topic);
                snprintf(topic, sizeof(topic), "D/%s/#", node->sn);
                mqtt_session_subscribe(mqtt_session, topic);
                snprintf(topic, sizeof(topic), "RTU/%s/#", node->sn);
                mqtt_session_subscribe(mqtt_session, topic);
            }
            else if (node->port == VINTF_TCP)
            {
                // TCP的数据经由前置机到网关内部
                snprintf(topic, sizeof(topic), "F/%s/#", node->sn);
                mqtt_session_subscribe(mqtt_session, topic);
            }
        }
    }

    //前置机topic
    mqtt_session_subscribe(mqtt_session, "F/SearchSN");
}

// 建立与broker之间的MQTT连接
int vint_external_client_init(vint_var_t *var, char *filename)
{
    char clientId[MAX_CLIENT_ID_LEN] = {0};

    snprintf(clientId, MAX_CLIENT_ID_LEN, "VINT_%s", var->sn_str);
    var->session_ext = mqtt_session_new(clientId, (void*)var);
    if (var->session_ext == NULL) return -1;

    vint_external_cfg_parse(var, filename);
    mqtt_session_set_opts(var->session_ext, DEFAULT_QOS, KEEPALIVEINTERVAL);
    mqtt_session_set_callbacks(var->session_ext, vint_external_mqtt_handle_recv_msg, NULL);
    vint_ex_subscribe_all(var);
    mqtt_session_start(var->session_ext);
}

