package com.cisdi.data.DIClient.protocol.utils;

import com.alibaba.fastjson.JSON;
import com.cisdi.data.common.exception.BusinessException;
import com.cisdi.data.sdk.service.DynamicCodecService;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: lhp
 * @date: 2019/10/8
 **/
public class IXComCodecService {
	
	public Map<String, Object> decode(String runId, IXComActionParamDTO dto, byte[] data, Charset charset) {
        int sumLen = 0;

        try{
            sumLen = dto.getPropertyList().stream().mapToInt(IXComActionParamDTO.PropertyConfig::getFixedLength).sum();
        } catch (Exception e) {
            throw new BusinessException("连接id:" + String.valueOf(runId) + "电文号:" + String.valueOf(dto.getMsgKey()) +
                " ixcom29d解析数据长度失败", e);
        }

        if (sumLen != data.length) {
            if(dto.getPropertyList().get(dto.getPropertyList().size()-1).getFixedLength()!=0)
            {
                throw new BusinessException("连接id:" + String.valueOf(runId) + "电文号:" + String.valueOf(dto.getMsgKey()) +
                        " ixcom29d解析长度与数据长度不一致错误, 解析数据长度为: " + data.length + " 配置长度为: " + sumLen);
            }
        }

        Map<String, Object> map = new HashMap<>();
        
        ByteBuffer byteBuffer = ByteBuffer.wrap(data);

        for(int i=0;i<dto.getPropertyList().size();i++)
        {
            if (dto.getPropertyList().get(i) != null) {
                IXComActionParamDTO.PropertyConfig property=dto.getPropertyList().get(i);
                if(i==dto.getPropertyList().size()-1&&property.getFixedLength()==0)
                {
                    property.setFixedLength(byteBuffer.array().length-sumLen);
                }
                Object object = IXComConverterUtils.convertProperty(property, byteBuffer, charset,runId,dto.getMsgKey());
                if (object != null) {
                    map.put(property.getPropertyId(), object);
                }
            }
        }
        return map;
	}

    /**
     * 测试类*/
    public static class TestDynamicCodecHelperImpl implements DynamicCodecService {

        @Override
        public String getName() {
            return null;
        }

        @Override
        public String findByRunIdAndMsgKey(String runId, String msgKey) {
            IXComActionParamDTO dto = new IXComActionParamDTO();
            IXComActionParamDTO.PropertyConfig config = new IXComActionParamDTO.PropertyConfig();
            config.setPropertyId("boolean");
            config.setPropertyType(IXComActionParamDTO.PropertyType.BOOLEAN);
            config.setFixedLength(1);
            dto.appendProperty(config);
            IXComActionParamDTO.PropertyConfig config1 = new IXComActionParamDTO.PropertyConfig();
            config1.setPropertyId("short");
            config1.setPropertyType(IXComActionParamDTO.PropertyType.SHORT);
            config1.setFixedLength(1);
            IXComActionParamDTO.PropertyConfig config2 = new IXComActionParamDTO.PropertyConfig();
            config2.setPropertyId("int");
            config2.setPropertyType(IXComActionParamDTO.PropertyType.INT);
            config2.setFixedLength(4);
            IXComActionParamDTO.PropertyConfig config3 = new IXComActionParamDTO.PropertyConfig();
            config3.setPropertyId("long");
            config3.setPropertyType(IXComActionParamDTO.PropertyType.LONG);
            config3.setFixedLength(4);
            IXComActionParamDTO.PropertyConfig config4 = new IXComActionParamDTO.PropertyConfig();
            config4.setPropertyId("string");
            config4.setPropertyType(IXComActionParamDTO.PropertyType.STRING);
            config4.setFixedLength(10);
            IXComActionParamDTO.PropertyConfig config5 = new IXComActionParamDTO.PropertyConfig();
            config5.setPropertyId("double");
            config5.setPropertyType(IXComActionParamDTO.PropertyType.DOUBLE);
            config5.setFixedLength(8);

            IXComActionParamDTO.PropertyConfig config6 = new IXComActionParamDTO.PropertyConfig();
            config6.setPropertyId("");
            config6.setPropertyType(IXComActionParamDTO.PropertyType.PLACEHOLDER);
            config6.setFixedLength(6);
            dto.appendProperty(config1);
            dto.appendProperty(config2);
            dto.appendProperty(config3);
            dto.appendProperty(config4);
            dto.appendProperty(config5);
            dto.appendProperty(config6);

            return JSON.toJSONString(dto);
        }

        @Override
        public Boolean judgeBigEndianByRunId(String runId) {
            return null;
        }

        @Override
        public Boolean judgeBigEndianByDeviceId(String deviceId) {
            return true;
        }

		@Override
		public String findByRunIdAndMsgKeyNoCache(String runId, String msgKey) {
			// TODO Auto-generated method stub
			return null;
		}
    }

    @SuppressWarnings("unused")
	public static void main(String[] args) {
        IXComCodecService service = new IXComCodecService();
        Map<String, Object> map = new HashMap<>();
        map.put("boolean", true);
        map.put("short", Short.valueOf((short) 0xf2));
        map.put("int", Integer.valueOf(0x03));
        map.put("long", Long.valueOf(0xf4L));
        map.put("string",new String("1234567890"));
        map.put("double", Double.valueOf(-123123213.3));
        Map<String, Object> map1 = JSON.parseObject(JSON.toJSONString(map));
       // System.out.println(Arrays.toString(service.encode(map, "1","2", "1")));
       // System.out.println(service.encode(map, "1","2","1").length);
        //System.out.println(service.decode(service.encode(map, "1","2","1"), "1", "2", "1"));
    }
}
