#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/time.h>
#include <sys/resource.h>

#include "vint_common.h"
#include "libubox/utils.h"
#include "dy_utils/dy_ipc.h"

static int receive_data_package(vint_var_t *var, char *sn, int mi, time_t now, char *payload, char *identifier)
{
	char *data_tmp = NULL;
    cJSON *root = NULL;
	cJSON *tag = NULL;
	char topic[256] = {0};

	tag = cJSON_Parse(payload);
	GET_JSON_VALUE_INT(root, "mi", mi);
	GET_JSON_VALUE_INT(root, "time", now);
	
	root = cJSON_CreateObject();
	cJSON_AddStringToObject(root, "sn", sn);
	cJSON_AddNumberToObject(root, "mi", mi);
	cJSON_AddNumberToObject(root, "time", now);
	cJSON_AddStringToObject(root, "identifier", identifier);
	
	cJSON_AddItemToObject(root, "tags", tag);
	data_tmp = cJSON_Print(root);
	dy_syslog(LOG_DEBUG, "data_tmp:%s", data_tmp);
	snprintf(topic, TOPIC_MAX_LEN, "ipc/%s/%s/device/%s/data_filtered/service/%s", var->sn_str, "VINT_MQTT", sn, identifier);
    ipc_session_publish(var->session_int, topic, data_tmp, strlen(data_tmp));

	cJSON_Delete(root);
	free(data_tmp);
}

int vint_send_mqtt_data_lnxall_dtu(vint_var_t *var, pp_regulate_signal_t *regulate_data)
{
    uint16_t payloadLen = regulate_data->len;
    char *payload = NULL;
    char *sn = regulate_data->sn;
    char topic[256] = {0};
    int ret = 0;
    time_t ts = time(NULL);

    payload = calloc(1, payloadLen + 1);
    if (payload == NULL)
    {
        dy_syslog(LOG_ERR, "malloc failed");
        ret = -1;
        goto out;
    }
	cJSON *root = cJSON_Parse(regulate_data->data);
	GET_JSON_VALUE_STRING(root, "topic", topic);
	
	dy_syslog(LOG_DEBUG, "11 topic:%s", topic);
	
    dy_syslog_hex(LOG_DEBUG, regulate_data->data, payloadLen, "payload data");
    memcpy(payload, regulate_data->data, payloadLen);
	dy_syslog(LOG_DEBUG, "22 topic:%s", topic);
    dy_syslog_hex(LOG_DEBUG, payload, payloadLen, "	len %d			VINT->SN:%s		topic:%s", payloadLen, sn, topic);

    //store the identifier
    {
        char key_str[64] = {0};
        regulate_cmd_backup_t fields;

        strcpy(fields.src_identifier, regulate_data->src_identifier);
        strcpy(fields.sn, sn);
        fields.mi = regulate_data->mi;

        sprintf(key_str, "%s_%d", sn, (unsigned short)regulate_data->mi);
        var->identifier_backup.insert(&var->identifier_backup, key_str, &fields, sizeof(fields));
    }
	if(strlen(topic) == 0)
		sprintf(topic, "M/%s/Set_Config", sn);
	dy_syslog(LOG_DEBUG, "33 topic:%s", topic);
    mqtt_session_publish(var->session_ext, topic, payload, payloadLen);
    free(payload);
	cJSON_Delete(root);
out:
    return ret;
}

int handle_lnxall_dtu(vint_var_t *var, mqtt_message_t *mqtt_msg, node_cfg_t *node)
{
    int ret = 0;
    char cmd[64] = {0};
    int mi = 0;
    char topic[256] = {0};
    time_t now = time(NULL);

    sscanf(mqtt_msg->topic, "%*[^/]/%*[^/]/%s", cmd);

    if (strcmp(cmd, "Evt_Login") == 0)
    {
        cJSON *root = NULL;
        cJSON *mqtt_json = cJSON_CreateObject();
        char *data_tmp = NULL;

        root = cJSON_Parse(mqtt_msg->payload);
        GET_JSON_VALUE_INT(root, "mi", mi);

        sprintf(topic, "M/%s/Rsp_Login", node->sn);

        cJSON_AddNumberToObject(mqtt_json, "mi", mi);
        cJSON_AddNumberToObject(mqtt_json, "time", now);
        cJSON_AddNumberToObject(mqtt_json, "error_code", 0);

        data_tmp = cJSON_Print(mqtt_json);

        mqtt_session_publish(var->session_ext, topic, data_tmp, strlen(data_tmp));

        free(data_tmp);
        cJSON_Delete(mqtt_json);
        cJSON_Delete(root);
    }
    else if (strcmp(cmd, "Evt_Heartbeat") == 0)
    {
        cJSON *root = NULL;
        cJSON *mqtt_json = cJSON_CreateObject();
        char *data_tmp = NULL;

        root = cJSON_Parse(mqtt_msg->payload);
        GET_JSON_VALUE_INT(root, "mi", mi);

        sprintf(topic, "M/%s/Rsp_Heartbeat", node->sn);

        cJSON_AddNumberToObject(mqtt_json, "mi", mi);
        cJSON_AddNumberToObject(mqtt_json, "time", now);

        data_tmp = cJSON_Print(mqtt_json);

        mqtt_session_publish(var->session_ext, topic, data_tmp, strlen(data_tmp));

        free(data_tmp);
        cJSON_Delete(mqtt_json);
        cJSON_Delete(root);
    }
    else if (strcmp(cmd, "transparent") == 0)
    {
        char *encode_str = NULL;
        int len;
        char *data_tmp = NULL;
        char port_str[8] = {0};
        cJSON *root = NULL;

        root = cJSON_Parse(mqtt_msg->payload);
        GET_JSON_VALUE_INT(root, "mi", mi);
        GET_JSON_VALUE_STRING(root, "port", port_str);
        GET_JSON_VALUE_DY_STRING(root, "data", encode_str);

        free(encode_str);
        cJSON_Delete(root);
    }
    else if (strcmp(cmd, "Evt_DataReport") == 0)
    {
        int len;
        char *data_tmp = NULL;
        char port_str[8] = {0};
        cJSON *root = NULL;
        char identifier[64] = {0};
        char sn[SN_MAX_LEN] = {0};
        cJSON *mqtt_json = cJSON_CreateObject();

        root = cJSON_Parse(mqtt_msg->payload);
        GET_JSON_VALUE_INT(root, "mi", mi);
        GET_JSON_VALUE_STRING(root, "identifier", identifier);
        GET_JSON_VALUE_STRING(root, "sn", sn);
        if (strlen(identifier) == 0)
        {
            strcpy(identifier, "post");
        }
        if (strlen(sn) == 0)
        {
            strcpy(sn, node->sn);
        }

        cJSON_AddStringToObject(mqtt_json, "sn", sn);
        cJSON_AddNumberToObject(mqtt_json, "mi", mi);
        cJSON_AddNumberToObject(mqtt_json, "time", now);
        cJSON_AddStringToObject(mqtt_json, "identifier", identifier);
		cJSON *tags = cJSON_GetObjectItem(root, "tags");
		if(tags)
		{
			char *tags_str = cJSON_Print(tags);
			cJSON *jtag = cJSON_Parse(tags_str);
        	cJSON_AddItemToObject(mqtt_json, "tags", jtag);
			free(tags_str);
		}
		
		data_tmp = cJSON_Print(mqtt_json);
		dy_syslog(LOG_DEBUG, "data_tmp:%s", data_tmp);
		snprintf(topic, TOPIC_MAX_LEN, "ipc/%s/%s/device/%s/data_filtered/service/%s", var->sn_str, "VINT_MQTT", sn, identifier);
	    ipc_session_publish(var->session_int, topic, data_tmp, strlen(data_tmp));
		
        cJSON_Delete(mqtt_json);
        cJSON_Delete(root);
    }
	else if (strcmp(cmd, "Rsp_ServerRedirect") == 0)
    {
    	receive_data_package(var, node->sn, mi, now, mqtt_msg->payload, "Set_ServerRedirect");
    }
	else if (strcmp(cmd, "Rsp_Reboot") == 0)
    {
    	receive_data_package(var, node->sn, mi, now, mqtt_msg->payload, "Set_Reboot");
    }
	else if (strcmp(cmd, "Rsp_Upgrade") == 0)
    {
    	receive_data_package(var, node->sn, mi, now, mqtt_msg->payload, "Upgrade");
    }
	else if (strcmp(cmd, "Evt_SystemInfo") == 0 || strcmp(cmd, "Evt_NetworkInfo") == 0)
    {
    	receive_data_package(var, node->sn, mi, now, mqtt_msg->payload, cmd);
    }

    dy_syslog(LOG_DEBUG, "handle lnxall DTU protocol data node:%s topic:%s", node->sn, mqtt_msg->topic);

    return ret;
}