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.entity.TbRseCtlr;
import com.its.dsrc.entity.TbRseCtrlHs;
import com.its.dsrc.process.DbmsData;
import com.its.dsrc.process.DbmsDataProcess;
import com.its.dsrc.process.DbmsDataType;
import com.its.dsrc.xnettcp.dsrc.handler.DsrcAsn1ServerIdleStatePacketHandler;
import com.its.dsrc.xnetudp.service.CenterCommResponseService;
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() {
        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();
        int  rejectPacketNmbr = reject.getDatexRejectPacketNbr().value.intValue();
        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);
            //command.setRSPS_TYPE("1");  // 명령 실패로 설정
            // 데이터베이스에 저장하고 운영단말로 전송한다.
            CenterCommResponseService responseService = (CenterCommResponseService) AppUtils.getBean(CenterCommResponseService.class);
            responseService.response(this.obj, command, (byte) 0x01);   // 명령 실패로 설정
            this.dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_CTLR_STTS, false, command));
        }
        return true;
    }
}
