package com.zt.plat.module.qms.iot.tcpserver;

import com.zt.plat.module.qms.iot.tcpserver.handler.IotClientHandler;
import com.zt.plat.module.qms.iot.tcpserver.handler.IotDeviceHandler;
import com.zt.plat.module.qms.iot.tcpserver.handler.IotHander;
import com.zt.plat.module.qms.iot.tcpserver.handler.IotHeartbeatHandler;
import com.zt.plat.module.qms.iot.tcpserver.proxy.ProxyProtocolDecoder;
import com.zt.plat.module.qms.iot.tcpserver.proxy.ProxyProtocolMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import tech.zzjc.tio.common.starter.annotation.TioServerMsgHandler;
import tech.zzjc.tio.core.ChannelContext;
import tech.zzjc.tio.core.TioConfig;
import tech.zzjc.tio.core.exception.LengthOverflowException;
import tech.zzjc.tio.core.exception.TioDecodeException;
import tech.zzjc.tio.core.intf.Packet;
import tech.zzjc.tio.core.utils.ByteBufferUtils;
import tech.zzjc.tio.server.intf.ServerAioHandler;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

/**
 * <b>IotServerMsgHandler</b>
 * <p>
 * 更新历史：
 * <pre> 版本         更新时间            更新者        更新内容<hr/>
 * V1.0      2019年9月10日          王兴荣         Add</pre>
 * <b>Copyright (C)  云南志者竟成科技有限公司</b> 
 * <p>
 * @author 王兴荣 &lt;xingrong_wang@will-way.cn&gt;
 * @version V1.0 
 * @since 2019年9月10日
 */
@Slf4j
@TioServerMsgHandler
public class IotServerMsgHandler implements ServerAioHandler {
    
    @Autowired
    private IotClientHandler iotClientHandler;
    
    @Autowired
    private IotDeviceHandler iotDeviceHandler;
    
    @Autowired
    private IotHeartbeatHandler iotHeartbeatHandler;

    @Override
    public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws TioDecodeException {
    	//解析代理协议
    	if (ProxyProtocolDecoder.isProxyProtocolEnabled(channelContext)) {
    		try {
    			// 标记
    			buffer.mark();// 解析 proxy 协议
    			ProxyProtocolMessage message = ProxyProtocolDecoder.decodeForTest(buffer, readableLength);
    			// 半包的情况
    			if (message == null) {
    				return null;
    			}
    			// 清除协议 key
    			ProxyProtocolDecoder.removeProxyProtocol(channelContext);
    			// 设置客户端代理节点
    			String protocol = message.getProtocol();
//    			if ("UNKNOWN".equals(protocol)) {
//    				channelContext.setProxyClientNode(new Node("UNKNOWN", message.getDestinationPort()));
//    			} else {
//    				Node realNode = new Node(message.getSourceAddress(), message.getSourcePort());
//    				realNode.setProtocol("TCP");
//    				channelContext.setClientNode(realNode);
//    				channelContext.setProxyClientNode(new Node(message.getDestinationAddress(), message.getDestinationPort()));
//    			}
	        	channelContext.set("realClientIp", message.getSourceAddress());
	        	channelContext.set("realClientPort", message.getSourcePort());
	        	channelContext.set("realClientProtocol", protocol);
			} catch (TioDecodeException e) {
				// 清除协议 key，重置 buffer
				ProxyProtocolDecoder.removeProxyProtocol(channelContext);
				buffer.reset();
			}
    		return IgnorePacket.INSTANCE;
    	}
        String line = null;
        try {
            line = ByteBufferUtils.readLine(buffer, null);
        } catch (Exception | LengthOverflowException e) {
            throw new TioDecodeException(e);
        }
        if (line == null) {
            return null;
        }
        //清除左右两边的空格或换行
        line = line.trim();
        log.debug("line = " + line);
        IotPacket packet = new IotPacket();
        packet.setBody(line.getBytes(Charset.forName(IotPacket.CHARSET)));
        return packet;
    }

    @Override
    public ByteBuffer encode(Packet packet, TioConfig tioConfig, ChannelContext channelContext) {
        IotPacket iotPacket = (IotPacket) packet;
        byte[] body = iotPacket.getBody();
        // 消息长度
        int bodyLen = body.length;
        // 分配一个新的字节缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(bodyLen);
        buffer.order(tioConfig.getByteOrder());
        // 写入消息体
        buffer.put(body);
        return buffer;
    }

    @Override
    public void handler(Packet packet, ChannelContext channelContext) throws Exception {
        IotPacket iotPacket = null;
        byte[] body = null;
    	if (packet instanceof IotPacket) {
    		iotPacket = (IotPacket) packet;
    		body = iotPacket.getBody();
		}
        if (body != null) {
            String text = new String(body, IotPacket.CHARSET);
            IotHander iotHander = null;
            //心跳消息
            if (IotPacket.PING.equalsIgnoreCase(text)) {
                iotHander = iotHeartbeatHandler;
            } else if (text.startsWith("{") && text.endsWith("}")) { //如果是json格式，为客户端协议
                iotHander = iotClientHandler;
            } else { //设备协议
                iotHander = iotDeviceHandler;
            }
            iotHander.hander(iotPacket, channelContext);
        }
        return;
    }

}
