package com.its.dsrc.xnettcp.dsrc.process.response;

import com.beanit.asn1dsrc.dsrc.C2CAuthenticatedMessage;
import com.beanit.asn1dsrc.dsrc.PDUs;
import com.beanit.asn1dsrc.dsrc.Reject;
import com.beanit.asn1dsrc.dsrc.RejectType;
import com.its.app.AppUtils;
import com.its.app.utils.NettyUtils;
import com.its.dsrc.config.RunningConfig;
import com.its.dsrc.dao.mapper.RseCtlrMapper;
import com.its.dsrc.entity.TbRseCtlr;
import com.its.dsrc.entity.TbRseCtrlHs;
import com.its.dsrc.process.DbmsDataProcess;
import com.its.dsrc.xnettcp.dsrc.handler.DsrcAsn1ServerIdleStatePacketHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class RejectResponse implements DsrcAsn1Response {
    private TbRseCtlr obj;
    private ChannelHandlerContext ctx;
    private C2CAuthenticatedMessage c2c;
    private DbmsDataProcess dbmsDataProcess;

    public RejectResponse(TbRseCtlr obj, ChannelHandlerContext ctx, C2CAuthenticatedMessage c2c) {
        this.obj = obj;
        this.ctx = ctx;
        this.c2c = c2c;
        this.dbmsDataProcess = (DbmsDataProcess) AppUtils.getBean(DbmsDataProcess.class);
    }

    @Override
    public boolean response(RunningConfig runningConfig) {
        String ipAddress = NettyUtils.getRemoteIpAddress(this.ctx.channel());
        log.info("RejectResponse.response: {}", ipAddress);

        PDUs pdus = this.c2c.getPdu();
        Reject reject = pdus.getReject();
        if (reject == null) {
            log.error("RejectResponse.response: {}, reject data null", ipAddress);
            return false;
        }

        long dataPacketNmbr = c2c.getDatexDataPacketNumber().value.longValue();
        Long  rejectPacketNmbr = reject.getDatexRejectPacketNbr().value.longValue();
        RejectType rejectType = reject.getDatexRejectType();

        TbRseCtrlHs command = null;
        int rejectCode = 0;
        if (rejectType.getDatexRejectLoginCd() != null) {
            rejectCode = rejectType.getDatexRejectLoginCd().value.intValue();
            log.error("RejectResponse.response: {}. RejectLoginCd: dataPacketNmbr: {}, rejectPacketNmbr: {}, rejectCode: {}", ipAddress, dataPacketNmbr, rejectPacketNmbr, rejectCode);
            // TODO: 클라이언트와의 연결을 종료한다.
            DsrcAsn1ServerIdleStatePacketHandler.disconnectChannel(this.obj, this.ctx.channel());
        }
        else if (rejectType.getDatexRejectSubscriptionCd() != null) {
            rejectCode = rejectType.getDatexRejectSubscriptionCd().value.intValue();
            log.error("RejectResponse.response: {}. RejectSubscription: dataPacketNmbr: {}, rejectPacketNmbr: {}, rejectCode: {}", ipAddress, dataPacketNmbr, rejectPacketNmbr, rejectCode);
            this.obj.removeRegisteredCommands(rejectPacketNmbr, true);
            command = this.obj.getUserCommands(rejectPacketNmbr);
        }
        else if (rejectType.getDatexRejectPublicationCd() != null) {
            rejectCode = rejectType.getDatexRejectPublicationCd().value.intValue();
            log.error("RejectResponse.response: {}. RejectPublication: dataPacketNmbr: {}, rejectPacketNmbr: {}, rejectCode: {}", ipAddress, dataPacketNmbr, rejectPacketNmbr, rejectCode);
            this.obj.removeRegisteredCommands(rejectPacketNmbr, true);
            command = this.obj.getUserCommands(rejectPacketNmbr);
        }

        if (command != null) {
            log.error("RejectResponse.response: {}. Reject User Command: dataPacketNmbr: {}, rejectPacketNmbr: {}, rejectCode: {}", ipAddress, dataPacketNmbr, rejectPacketNmbr, rejectCode);
            this.obj.removeUserCommands(rejectPacketNmbr);
            // TODO: 제어명령 전송정보 전송(실패)
            command.setRspsType("4");  // 명령 실패(REJECT)로 설정
            RseCtlrMapper mapper = (RseCtlrMapper) AppUtils.getBean(RseCtlrMapper.class);
            mapper.updateRseCtrlHs(command);
        }
        return true;
    }
}
