package com.cisdi.data.RFID.gateway;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cisdi.data.sdk.consts.ServiceName;
import com.cisdi.data.sdk.gateway.message.SocketMessage;
import com.cisdi.data.sdk.service.SendService;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

public class RfidClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    private static final Logger logger = LoggerFactory.getLogger(RfidClientHandler.class);
    private static final Charset Encode_Charset = Charset.forName("UTF-8");
    private static final String HEARTBEAT_CODE = "HeartBea";

    private RfidClient rfidClient;

    private RfidTaskStartVo startVo;

    public RfidClientHandler(RfidTaskStartVo startVo, RfidClient rfidClient) {
        this.startVo = startVo;
        this.rfidClient = rfidClient;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {

        try {
            List<RfidItemVo> decode = RfidVoDecoder.Decode(msg);
            if(decode.size() == 1 && HEARTBEAT_CODE.equalsIgnoreCase(decode.get(0).getCode())) {
                logger.info("永锋物流Rfid {}，启用心跳：{} ， 心跳 vo:{}", rfidClient.getChannel(),
                        startVo.getCustomParam() == null ? false : startVo.getCustomParam().getEnableHeartbeat(),
                        decode);
                rfidClient.setLastHeartbeatTime(System.currentTimeMillis());
                return;
            }

            decode.forEach((RfidItemVo i) -> {
                i.setServerIp(startVo.getSocketParam().getPeerIp());
                i.setServerPort(startVo.getSocketParam().getPeerPort());
            });


            if (startVo.getGatewayBase() != null && Boolean.TRUE.equals(startVo.getGatewayBase().getInstanceVo().getLogOpen())) {
                logger.info("永锋物流Rfid {} vo:{} ", rfidClient.getChannel(), decode);
            }

            if (startVo.getGatewayBase() != null && startVo.getServiceProvider() != null) {
                Map<String, Object> data = new HashMap<>();
                SendService service = (SendService) startVo.getServiceProvider().getByName(ServiceName.Send);
                SocketMessage socketMessage = startVo.getGatewayBase().buildSocketMessage();
                socketMessage.setDeviceId(startVo.getDeviceId());
                socketMessage.setProviderCode(null);
                socketMessage.setMsgKey("666");
                data.put("data", decode);
                String jsonString = JSON.toJSONString(data, SerializerFeature.WriteMapNullValue);
                byte[] body = jsonString.getBytes(Encode_Charset);
                socketMessage.setData(body);
                logger.info("socketMess" + socketMessage.toString());
                service.sendMessage(socketMessage);
            } else {
                logger.info("永锋物流Rfid收到消息{}", decode);
            }
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage(), e);
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        logger.info("{} channelActive active", ctx.channel());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("{} channelInactive inactive", ctx.channel());

        try {
            rfidClient.setChannel(null);
            logger.info("set channel to null raise reconnect");
        } finally {
            // 释放引用
            rfidClient = null;
        }

        super.channelInactive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable t) throws Exception {
        logger.error("exceptionCaught:{}", t);
        super.exceptionCaught(ctx, t);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        logger.error("userEventTriggered:{}", evt);
        super.userEventTriggered(ctx, evt);
    }
}
