#include "device_message.h"
#include "gd32f10x.h"
#include "string.h"
int parseIntField(const char *data, const char *field);
void parseStringField(const char *data, const char *field, char *value);
void addDevice(char *deviceString);
void addSensorListParams(char *paramString, DEVICE_PARAMS *device);
void addCommandListParams(char *paramString, DEVICE_PARAMS *device);
GATEWAY_PARAMS gateway_config_params = {0};

GATEWAY_PARAMS *get_gateway_config_params()
{
    return &gateway_config_params;
}
/***
***其主要分为了三层结构来做的最外层网关层，设备层，属性层
***其不用json解析，json消耗量太大，用关键字匹配去解析json数据用'}'和后一位']'去做结束判断依次从最内层往外层一层一层解析，解析完最内层的数据将'}'变为'A'防止外层去找结束符号时找到了内层
***/
//解析网关最外层的相关信息
int addGatewayParams(char *gatewayString)
{
	  parseStringField(gatewayString, "\"commandTopic\":\"", (char *)&gateway_config_params.commandTopic);
		parseStringField(gatewayString, "\"messageTopic\":\"", (char *)&gateway_config_params.messageTopic);

    parseStringField(gatewayString, "\"deviceId\":\"", (char *)&gateway_config_params.deviceId);
    parseStringField(gatewayString, "\"host\":\"", (char *)&gateway_config_params.host);
    gateway_config_params.port = parseIntField(gatewayString, "\"port\":");
		
    gateway_config_params.pollTime = parseIntField(gatewayString, "\"pollTime\":");
		gateway_config_params.baudrate=parseIntField(gatewayString, "\"baudrate\":");
		gateway_config_params.checkBit=parseIntField(gatewayString, "\"checkBit\":");
		gateway_config_params.dataBits=parseIntField(gatewayString, "\"dataBit\":");
		gateway_config_params.stopBit=parseIntField(gatewayString, "\"stopBit\":");
		gateway_config_params.inboundTime=parseIntField(gatewayString, "\"inboundTime\":");
		char *deviceString = strstr(gatewayString, "deviceList");//找到设备数组所处位置
    while (1)
    {
				addDevice(deviceString); // 往此节点下挂载设备信息
				deviceString=deviceString;//deviceString内容被内部数据改写了进行一次数据重加载
				deviceString = strstr(deviceString, "}");          // 移动到下一条属性
				deviceString[0]='A';
				deviceString++;
			  if(deviceString[0]==']')
				{
						break;
				}
    }
}
void addGatewayParamsJson(char *gatewayString)
{
	
}
//添加新的设备
//应其为多层嵌套结构所以其找到最内部对象{}后将其值改写，这样可以避免外部的结构再去寻找
void addDevice(char *deviceString)
{
	char *paramString = (char *)deviceString; // 属性指针
  DEVICE_PARAMS *newDevicePage = (DEVICE_PARAMS *)malloc(sizeof(DEVICE_PARAMS));
	newDevicePage->nextDevice = NULL;
	parseStringField(deviceString, "\"deviceId\":\"", (char *)&newDevicePage->deviceID);
  newDevicePage->protocol = parseIntField(deviceString, "\"protocol\":");
  newDevicePage->params = (PARAMS_PROTOCOL_COMMAND *)malloc(sizeof(PARAMS_PROTOCOL_COMMAND));	
	paramString = strstr(paramString, "\"sensorData\":["); // 找到该节点的轮询上发属性
	if(paramString!=NULL)
	{
		while(1)
		{
			 addSensorListParams(paramString, newDevicePage); // 解析一个属性并挂载该属性于该属性下
			 paramString = strstr(paramString, "}");          // 移动到下一条属性
			 paramString[0]='A';
			 paramString++;
			 if (paramString[0] == ']')
			 {
				 paramString = (char *)deviceString;//找完了设备层内的属性，将指针指向设备层一开始的位置，防止json导致的sensorList和commandData乱序问题
				 break;
			 }
		}
	}
		if(newDevicePage->protocol==MODBUS)  //如果为modbus的话解析写指令
		{
		paramString=deviceString;                                //移动到最开始的地方
		newDevicePage->MDBbigLittleFormat = parseIntField(paramString, "\"bigLittleFormat\":");
    newDevicePage->MDBdataType= parseIntField(paramString, "\"dataType\":");
		paramString = strstr(paramString, "\"commandData\":["); // 找到其轮询的写命令
		if(paramString!=NULL)//可能不存在commandData
		{
			while(1)
			{
				addCommandListParams(paramString, newDevicePage);
				paramString = strstr(paramString, "}");
				paramString[0]='A';
				paramString++;
				if (paramString[0] == ']')
				{
					paramString = (char *)deviceString;
					break;
				}
			}
		}
	}
	if(gateway_config_params.device_params==NULL)
	{
		gateway_config_params.device_params=newDevicePage;
	}else
	{
		DEVICE_PARAMS *current=gateway_config_params.device_params;
    while (current->nextDevice != NULL)
    {
      current = current->nextDevice;
    }
      current->nextDevice = newDevicePage;		
	}
}
/**
 * @brief  解析输入字符串的paramString数据,将数据保存到至该设备结构体下，此处解析sensorList
 * @param  uint8_t *paramString输入的字符串数据,DEVICE_PARAMS *device节点信息
 * @retval 无
 */
void addSensorListParams(char *paramString, DEVICE_PARAMS *device)
{
    switch (device->protocol)
    {
    case DLT645_97:
    case DLT645_07:
		{
        READ_DLT645_COMMAND *read_dlt645_command = malloc(sizeof(READ_DLT645_COMMAND));
				READ_MODBUS_COMMAND *read_modbus_command =NULL;
        read_dlt645_command->Identification = parseIntField(paramString, "\"identifier645\":");
        parseStringField(paramString, "\"identifier\":\"", (char *)&read_dlt645_command->keyword);
        char *string = malloc(13);
        parseStringField(paramString, "\"deviceID645\":\"", string);
        for (int j = 0; j < 6; j++)
        {
          uint8_t byte;
          sscanf((const char *)&string[j * 2], "%2hhx", &byte);
          read_dlt645_command->deviceID645[j]=byte;
        }
        free(string);
        if (device->params->node_read_dlt645_command == NULL)
        {
            device->params->node_read_dlt645_command = read_dlt645_command;
        }
        else
        {
            READ_DLT645_COMMAND *current = device->params->node_read_dlt645_command;
            while (current->nextParams != NULL)
            {
                current = current->nextParams;
            }
            current->nextParams = read_dlt645_command;
        }
			}
        break;
    case MODBUS:
		{
        READ_MODBUS_COMMAND *read_modbus_command = malloc(sizeof(READ_MODBUS_COMMAND));
				READ_DLT645_COMMAND *read_dlt645_command = NULL;
				parseStringField(paramString,"\"identifier\":\"",(char *)&read_modbus_command->keyword);
        read_modbus_command->decimalPoint = parseIntField(paramString, "\"precise\":");
        read_modbus_command->functionCode = parseIntField(paramString, "\"rFunctionCode\":");
        read_modbus_command->slaveAddress = parseIntField(paramString, "\"slaveAddress\":");
        read_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":");
        read_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":");
        if (device->params->node_read_modbus_command == NULL)
        {
            device->params->node_read_modbus_command = read_modbus_command;
        }
        else
        {
            READ_MODBUS_COMMAND *current = device->params->node_read_modbus_command;
            while (current->nextParams != NULL)
            {
                current = current->nextParams;
            }
            current->nextParams = read_modbus_command;
        }
			}
        break;
    default:
        break;
    }
}
void addCommandListParams(char *paramString, DEVICE_PARAMS *device)
{
	
 	WRITE_MODBUS_COMMAND *write_modbus_command=malloc(sizeof(WRITE_MODBUS_COMMAND));
	parseStringField(paramString,"\"identifier\":\"",(char *)&write_modbus_command->keyword);
	write_modbus_command->registerByteNum = parseIntField(paramString, "\"registerByteNum\":");
	write_modbus_command->functionCode=parseIntField(paramString, "\"wFunctionCode\":");
	write_modbus_command->slaveAddress=parseIntField(paramString, "\"slaveAddress\":");
	write_modbus_command->registerAddress = parseIntField(paramString, "\"registerAddress\":");
	if(device->params->node_write_modbus_command == NULL)
	{
		device->params->node_write_modbus_command=write_modbus_command;
	}
	else
	{
		WRITE_MODBUS_COMMAND *current=device->params->node_write_modbus_command;
    while (current->nextParams != NULL)
    {
      current = current->nextParams;
    }
    current->nextParams = write_modbus_command;		
	}
}
// 提取int数据如果没有提取到数据则返回-1；提取到返回正确的值
int parseIntField(const char *data, const char *field)
{
    char *ptr = strstr(data, field) + strlen(field);
    int value;
    value = strtol(ptr, &ptr, 10);
    return value;
}
/*

*/
// 提取string字符串
void parseStringField(const char *data, const char *field, char *value)
{
    char *ptr = strstr(data, field) + strlen(field);
    sscanf(ptr, "%[^\"],", value);
}