package com.its.vds.xnettcp.center.handler;

import com.its.app.AppUtils;
import com.its.app.utils.NettyUtils;
import com.its.vds.dao.mapper.VdsCtlrMapper;
import com.its.vds.dto.TbVdsCtlrDto;
import com.its.vds.service.AppRepositoryService;
import com.its.vds.xnettcp.center.protocol.CenterProtocol;
import com.its.vds.xnettcp.center.protocol.CenterReqFramePacket;
import com.its.vds.xnettcp.center.protocol.CenterResProtocol;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;

@Slf4j
@Component
@RequiredArgsConstructor
@ChannelHandler.Sharable
public class CenterTcpServerInboundHandler extends ChannelInboundHandlerAdapter {

    private final AppRepositoryService repoService;

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        VdsCtlrMapper mapper = (VdsCtlrMapper) AppUtils.getBean(VdsCtlrMapper.class);
        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
        if (!(msg instanceof CenterReqFramePacket)) {
            log.error("[{}] | Received Data is not CenterReqFramePacket Object", NettyUtils.getRemoteIpAddress(ctx.channel()));
            return;
        }
        CenterReqFramePacket centerReqHead = (CenterReqFramePacket)msg;
        byte opCode = centerReqHead.getHead().getOpCode();
        byte[] body = centerReqHead.getBody();
        if (body == null) {
            return;
        }
        ByteBuffer msgBuffer = ByteBuffer.wrap(body);
        msgBuffer.order(CenterProtocol.byteOrder);
        if (opCode == CenterProtocol.INT_OP_DSRC_CONTROL_REQ) {
            long ctlrNmbr = msgBuffer.getLong();
            long ctrlSeq = msgBuffer.getLong();
            int devcType = msgBuffer.getInt();
            int cntlType = msgBuffer.getInt();

            //TbVmsCtrlHs ctrlHs = new TbVmsCtrlHs();
//            ctrlHs.setCtrlSeq(ctrlSeq);
//            ctrlHs.setDevcType(String.valueOf(devcType));
//            ctrlHs.setCntlType(String.valueOf(cntlType));
//            ctrlHs.setRspsType("0");

            //TbVmsCtlr obj = AppRepository.getInstance().getCtlrMap().get(String.valueOf(ctlrNmbr));
            TbVdsCtlrDto obj = this.repoService.getCtlrMap(ctlrNmbr);
            if (obj == null) {
                log.error("CenterTcpServerInboundHandler: Center Request Unknown RSE: [{}]", ctlrNmbr);
//                ctrlHs.setRspsType("9");  // 알수없는제어기
                ByteBuffer sendBuffer = CenterResProtocol.getResponse(opCode, (byte)(0xFF));
                ChannelFuture f = ctx.channel().writeAndFlush(sendBuffer);
                f.awaitUninterruptibly();
                if (f.isDone() || f.isSuccess()) {
                    log.info("CenterTcpServerInboundHandler: Response OK. Center Request Unknown RSE: [{}]", ctlrNmbr);
                } else {
                    log.error("CenterTcpServerInboundHandler: Response Failed. Center Request Unknown RSE: [{}]", ctlrNmbr);
                }
                //mapper.updateVmsCtrlHs(ctrlHs);
                return;
            }

            // 제어요청 패킷을 만든다
            int result = 3;//obj.reset(devcType, devcType, ctrlHs);
            byte resCode = (byte)0xF0;
            switch (result) {
                case 0: break;
                case 1:
                    log.error("CenterTcpServerInboundHandler: Center Request RSE Not Connect: [{}]", obj);
//                    ctrlHs.setRspsType("8");  // 통신불량
                    resCode = (byte)0xFE;
                    break;
                case 2:
                    log.error("RSE REQ RESET CONTROL Value Error: [{}] [{},{}]", ctlrNmbr, devcType, cntlType);
//                    ctrlHs.setRspsType("7");  // 제어값 이상
                    resCode = (byte)0xFD;
                    break;
                case 3:
                    log.error("RSE REQ CONTROL SEND Error: [{}] [{},{}]", ctlrNmbr, devcType, cntlType);
//                    ctrlHs.setRspsType("6");  // 데이터전송실패
                    resCode = (byte)0xFC;
                    break;
            }

            ByteBuffer sendBuffer = CenterResProtocol.getResponse(opCode, resCode);
            ChannelFuture f = ctx.channel().writeAndFlush(sendBuffer);
            f.awaitUninterruptibly();
            if (f.isDone() || f.isSuccess()) {
                log.info("CenterTcpServerInboundHandler: To Center Response OK. [{}]", ctlrNmbr);
            } else {
                log.error("CenterTcpServerInboundHandler: To Center Response Failed. [{}]", ctlrNmbr);
            }
            //mapper.updateVmsCtrlHs(ctrlHs);

        }

    }

}
