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

import com.beanit.asn1dsrc.dsrc.Accept;
import com.beanit.asn1dsrc.dsrc.C2CAuthenticatedMessage;
import com.beanit.asn1dsrc.dsrc.PDUs;
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.xnetudp.service.CenterCommResponseService;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

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

    public AcceptResponse(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.debug("AcceptResponse.response: {}", ipAddress);

        PDUs pdus = this.c2c.getPdu();
        Accept accept = pdus.getAccept();
        if (accept == null) {
            log.error("AcceptResponse.response: {}, accept data null", ipAddress);
            return false;
        }

        TbRseCtrlHs command = null;
        long dataPacketNmbr = c2c.getDatexDataPacketNumber().value.longValue();
        int acceptPacketNmbr = accept.getDatexAcceptPacketNbr().value.intValue();
        Accept.DatexAcceptType acceptType = accept.getDatexAcceptType();
        if (acceptType.getLogIn() != null) {
            // Login = 1, 여기는 들어오지 않는다.
            log.info("AcceptResponse.response: {}. Login: {} {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
        }
        else if (acceptType.getSingleSubscription() != null) {
            // SingleSubscription = 2
            // Publication = 3
            // 제어명령에 대한 응답, 제어목록에서 삭제하고 이력으로 저장한다.
            this.obj.removeRegisteredCommands(acceptPacketNmbr, true);
            command = this.obj.getUserCommands(acceptPacketNmbr);
            log.info("AcceptResponse.response: {}. SingleSubscription: {} {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
        }
        else if (acceptType.getPublication() != null) {
            // SingleSubscription = 2
            // Publication = 3
            // 제어명령에 대한 응답, 제어목록에서 삭제하고 이력으로 저장한다.
            this.obj.removeRegisteredCommands(acceptPacketNmbr, true);
            command = this.obj.getUserCommands(acceptPacketNmbr);
            log.info("AcceptResponse.response: {}. Publication: {} {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
        }
        else if (acceptType.getRegisteredSubscription() != null) {
            // RegisteredSubscription = 4
            // 요청에 대한 응답, 제어목록에서 삭제한다.
            this.obj.removeRegisteredCommands(acceptPacketNmbr, true);
            log.info("AcceptResponse.response: {}. RegisteredSubscription: {} {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
        }

        if (command != null) {
            log.info("AcceptResponse.response: {}. Accept User Command: {} {}", ipAddress, dataPacketNmbr, acceptPacketNmbr);
            this.obj.removeUserCommands(acceptPacketNmbr);
            //command.setRSPS_TYPE("0");  // 명령 성공으로 설정
            // 데이터베이스에 저장하고 운영단말로 전송한다.
            CenterCommResponseService responseService = (CenterCommResponseService) AppUtils.getBean(CenterCommResponseService.class);
            responseService.response(this.obj, command, (byte) 0x00);   // 명령 성공으로 설정
            this.dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_CTLR_STTS, false, command));
        }
        return true;
    }
}
