package com.cisdi.data.DIClient.protocol;

import com.alibaba.fastjson.JSON;
import com.cisdi.data.DIClient.protocol.utils.IXComActionParamDTO;
import com.cisdi.data.DIClient.protocol.utils.IXComCodecService;
import com.cisdi.data.common.exception.BusinessException;
import com.cisdi.data.sdk.consts.ServiceName;
import com.cisdi.data.sdk.gateway.message.SocketMessage;
import com.cisdi.data.sdk.procotol.SocketProtocol;
import com.cisdi.data.sdk.procotol.base.ProtocolBase;
import com.cisdi.data.sdk.procotol.message.SocketReturnMessage;
import com.cisdi.data.sdk.service.DynamicCodecService;
import com.cisdi.data.sdk.service.RouteService;
import com.cisdi.data.sdk.vo.DecodeVo;
import com.cisdi.data.sdk.vo.DeviceVo;
import com.cisdi.data.sdk.vo.ReturnVo;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * @author: lhp
 * @date: 2019/10/8
 **/
public class IXCom29DStringSocketProtocol extends ProtocolBase implements SocketProtocol {
	
    @Override
    public DecodeVo deCode(SocketMessage message) {
        if (message == null || message.getRunId() == null || message.getPropsMap() == null || message.getDeviceId() == null) {
            throw new BusinessException("解析入参错误1,msg为:" + message.toString());
        }        
        
        DynamicCodecService service = (DynamicCodecService)serviceProvider.getByName(ServiceName.DynamicCodec);
        if (service == null || !(service instanceof DynamicCodecService)) {
            throw new BusinessException("获取DynamicCodecService失败");
        }
        String paramObj = service.findByRunIdAndMsgKey(message.getRunId(), message.getMsgKey());
        Charset charset = Charset.forName(String.valueOf(message.getPropsMap().get("charset")));
        
        byte[] data = message.getData();
        
        if(data == null || paramObj == null) {
        	throw new BusinessException("解析入参错误2,msg为:" + message.toString());
        }
        
        IXComActionParamDTO dto = JSON.parseObject(paramObj, IXComActionParamDTO.class);
        dto.setMsgKey(message.getMsgKey());
        if(dto == null || dto.getPropertyList().size() == 0) {
        	throw new BusinessException("解析入参错误3,msg为:" + message.toString());
        }
        
        DecodeVo vo = new DecodeVo();
        
        IXComCodecService defaultService = new IXComCodecService();
        
        Map<String,Object> map = defaultService.decode(message.getRunId(), dto, data, charset);
        vo.setData(map);

        return vo;
    }

    @Override
    public SocketReturnMessage enCode(ReturnVo returnVo) {

        if (returnVo == null || returnVo.getValue() == null || returnVo.getDeviceId() == null) {
            throw new BusinessException("解析入参错误1,msg为:" + JSON.toJSONString(returnVo));
        }

        DynamicCodecService service = (DynamicCodecService)serviceProvider.getByName(ServiceName.DynamicCodec);
        if (service == null || !(service instanceof DynamicCodecService)) {
            throw new BusinessException("获取DynamicCodecService失败");
        }
        RouteService routeService = (RouteService)serviceProvider.getByName(ServiceName.Route);
        if (service == null || !(routeService instanceof RouteService)) {
            throw new BusinessException("获取RouteService失败");
        }
        DeviceVo deviceVo=routeService.findDeviceByDeviceId(returnVo.getDeviceId());
        if(deviceVo==null|| StringUtils.isBlank(deviceVo.getRunId()))
        {
            throw new BusinessException("获取DeviceVo失败");
        }
        String paramObj = service.findByRunIdAndMsgKey(deviceVo.getRunId(), returnVo.getMsgKey());
        Charset charset = Charset.forName(String.valueOf(Charset.forName("GBK")));
        IXComActionParamDTO dto = JSON.parseObject(paramObj, IXComActionParamDTO.class);
        if(dto == null || dto.getPropertyList().size() == 0) {
            throw new BusinessException("解析入参错误3,msg为:" + JSON.toJSONString(returnVo));
        }

        StringBuilder data= new StringBuilder();

        for(IXComActionParamDTO.PropertyConfig propertyConfig:dto.getPropertyList())
        {
            if(!returnVo.getValue().containsKey(propertyConfig.getPropertyId()))
            {
                throw new BusinessException("解析入参错误4,msg为:" + JSON.toJSONString(returnVo)+"在runId="+deviceVo.getRunId()+";msgKey="+returnVo.getMsgKey()+"的情况下，入参缺失"+propertyConfig.getPropertyId());
            }
            StringBuilder tmp= new StringBuilder(String.valueOf(returnVo.getValue().get(propertyConfig.getPropertyId())));
            int tmpLength= 0;
            try {
                tmpLength = tmp.toString().getBytes("GBK").length;
            } catch (UnsupportedEncodingException e) {
                throw new BusinessException("解析入参错误5,msg为:" + JSON.toJSONString(returnVo)+"在runId="+deviceVo.getRunId()+";msgKey="+returnVo.getMsgKey()+"的情况下，入参"+propertyConfig.getPropertyId()+"转换GBK失败"+e.getLocalizedMessage());
            }
            if(propertyConfig.getFixedLength()!=0&&tmpLength<propertyConfig.getFixedLength())
            {
                for(int i=0;i<(propertyConfig.getFixedLength()-tmpLength);i++)
                {
                    tmp.append(" ");
                }
            }
            else if(propertyConfig.getFixedLength()!=0&&tmp.length()>propertyConfig.getFixedLength())
            {
                throw new BusinessException("解析入参错误6,msg为:" + JSON.toJSONString(returnVo)+"在runId="+deviceVo.getRunId()+";msgKey="+returnVo.getMsgKey()+"的情况下，入参过长"+propertyConfig.getPropertyId());
            }
            data.append(tmp);
        }

    	SocketReturnMessage rt=new SocketReturnMessage();
        rt.setDeviceId(returnVo.getDeviceId());
        rt.setMsgId(returnVo.getMsgId());
        rt.setMsgKey(returnVo.getMsgKey());
        rt.setData(data.toString().getBytes());
    	return rt;
    }
}