package com.its.vms.xnettcp.vms.codec;

import com.its.app.utils.NettyUtils;
import com.its.vms.config.CommunicationConfig;
import com.its.vms.dto.TbVmsCtlrDto;
import com.its.vms.service.AppRepositoryService;
import com.its.vms.xnettcp.vms.handler.VmsServerIdleStateHandler;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

@Slf4j
@RequiredArgsConstructor
@Component
@ChannelHandler.Sharable
public class VmsTcpServerEncoder extends MessageToByteEncoder<Object> {

    private final CommunicationConfig communicationConfig;
    private final AppRepositoryService repoService;

     @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf byteBuf) throws Exception {

        String ipAddress = NettyUtils.getRemoteIpAddress(ctx.channel());
        Channel channel = ctx.channel();
        //TbVmsCtlr obj = AppRepository.getInstance().getCtlrIpMap().get(ipAddress);
        TbVmsCtlrDto obj = this.repoService.getIpAddrMap(ipAddress);
        if (obj == null) {
            log.error("VmsTcpServerEncoder.encode: Unknown Controller IP: {}. will be close.", ipAddress);
            VmsServerIdleStateHandler.disconnectChannel(null, channel);
            return;
        }

        MDC.put("id", obj.getLogKey());

        if (obj.getChannel() != null && (channel != obj.getChannel())) {
            log.error("VmsTcpServerEncoder.encode: {}, channel error, curr: {}, old: {}", ipAddress, channel.toString(), obj.getChannel().toString());
            VmsServerIdleStateHandler.disconnectChannel(obj, channel);
            return;
        }

        if (!channel.isOpen() || !channel.isActive()) {
            log.error("VmsTcpServerEncoder.encode: {}, isOpen: {}, isActive: {}. [{}]", ipAddress, channel.isOpen(), channel.isActive(), obj.getLogKey());
            VmsServerIdleStateHandler.disconnectChannel(obj, channel);
            return;
        }
//
//        if (!(msg instanceof C2CAuthenticatedMessage)) {
//            log.error("DsrcTcpServerEncoder.encode: {}, msg is not ByteBuffer. [{}]", ipAddress, obj.getLogKey());
//            VmsServerIdleStateHandler.disconnectChannel(obj, channel);
//            return;
//        }
//
//        C2CAuthenticatedMessage c2c = (C2CAuthenticatedMessage)msg;
//        try {
//            ReverseByteArrayOutputStream c2cBuff = new ReverseByteArrayOutputStream(2048);
//            ReverseByteArrayOutputStream pktBuff = new ReverseByteArrayOutputStream(2048);
//            int length = c2c.encode(c2cBuff);
//            if (length > 0) {
//                DatexDataPacket dataPkt = new DatexDataPacket();
//                dataPkt.setDatexVersionNumber(new BerEnum(1));  // version == 1
//                dataPkt.setDatexData(new BerOctetString(c2cBuff.getArray()));
//                dataPkt.setDatexCrcNbr(new BerOctetString(DsrcAsn1Crc16.getCrc16ToByteArray(c2cBuff.getArray())));  // crc
//
//                int encodeLength = dataPkt.encode(pktBuff);
//                byteBuf.writeBytes(pktBuff.getArray());
//                //log.info("SEND: Encoder: {}. ASN1 PACKET: {} Bytes, encodeLength: {} Bytes", ipAddress, length, encodeLength);
//                //log.info("SEND: Encoder: {}, C2CAuth: {}", ipAddress, c2c);
//                if (this.runningConfig.isDumpSend()) {
//                    byte[] debugBytes = new byte[byteBuf.readableBytes()];
//                    byteBuf.getBytes(byteBuf.readerIndex(), debugBytes);
//                    log.info("SEND: [{}], {} Bytes. {}", ipAddress, debugBytes.length, SysUtils.byteArrayToHex(debugBytes));
//                }
//            } else {
//                log.error("SEND: {}. C2CAuthenticatedMessage encode buffer length zero: will be closed.", ipAddress);
//                VmsServerIdleStateHandler.disconnectChannel(obj, channel);
//            }
//        } catch (Exception e) {
//            log.error("DsrcTcpServerEncoder.encode: SEND: {}. Exception Error: will be closed: {}. [{}]", ipAddress, e.toString(), obj.getLogKey());
//            VmsServerIdleStateHandler.disconnectChannel(obj, channel);
//        }
        //MDC.remove(obj.getLogKey());
        //MDC.clear();
    }
}
