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

import com.its.app.utils.NettyUtils;
import com.its.vds.dto.TbVdsCtlrDto;
import com.its.vds.service.AppRepositoryService;
import com.its.vds.xnettcp.vds.process.TcpServerRecvData;
import com.its.vds.xnettcp.vds.process.TcpServerRecvDataProcess;
import com.its.vds.xnettcp.vds.protocol.impl.VdsResFramePacket;
import io.netty.buffer.ByteBuf;
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;

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

    private final TcpServerRecvDataProcess tcpServerRecvDataProcess;
    private final AppRepositoryService appRepositoryService;

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

        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());

        if (!(msg instanceof VdsResFramePacket) && !(msg instanceof ByteBuf)) {
            log.error("[{}] | VdsServerPacketInboundHandler: Received Data is not VdsServerPacketInboundHandler Object", ipAddress);
            ctx.close();
            return;
        }

        VdsResFramePacket framePacket;
        if (msg instanceof VdsResFramePacket) {
            framePacket = (VdsResFramePacket) msg;
        }
        else {
            ByteBuf byteBuf = (ByteBuf)msg;
            final int readableBytes = byteBuf.readableBytes();
            if (readableBytes < 13) {
                log.error("[{}] | VdsServerPacketInboundHandler: Received Data readableBytes too small: {}, required min size: {}, will be closed",
                        ipAddress, readableBytes, 13);
                ctx.close();
                return;
            }

            TbVdsCtlrDto vdsObj = this.appRepositoryService.getIpAddrMap(ipAddress);
            if (vdsObj == null) {
                log.error("Receive: Packet {} Bytes, But Unknown IpAddress {}, will be closed.", readableBytes, ipAddress);
                ctx.close();
                return;
            }
            byte[] packets = new byte[readableBytes];
            byteBuf.readBytes(packets);
           framePacket = new VdsResFramePacket(vdsObj, packets, packets.length);
        }
        this.tcpServerRecvDataProcess.add(new TcpServerRecvData(TcpServerRecvData.DATA_TYPE_RES_PACKET, framePacket.getVdsObj(), ctx, framePacket));
    }

}
