package com.its.vms.xnettcp.vms.process.response.impl;

import com.its.vms.dto.TbVmsCtlrDto;
import com.its.vms.xnettcp.vms.process.TcpServerSendData;
import com.its.vms.xnettcp.vms.process.response.VmsResponse;
import com.its.vms.xnettcp.vms.protocol.VmsFramePacket;
import com.its.vms.xnettcp.vms.protocol.enums.eVmsOpCode;
import com.its.vms.xnettcp.vms.protocol.impl.dle.VmsDleFramePacket;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;

@Slf4j
@RequiredArgsConstructor
public class VmsResDisplayModuleStatus implements VmsResponse {

    private final TbVmsCtlrDto vmsObj;
    private final VmsFramePacket resFramePacket;
    private int x;  // (X축) VMS 모듈수 //가로
    private int y;  // (Y축) VMS 모듈수 //세로
    private String stts;

    @Override
    public boolean process() {

        this.x = 0;
        this.y = 0;
        this.stts = "";

        byte[] body = this.resFramePacket.getBody();
        log.info("VmsResDisplayModuleStatus.process: VMS {}, body length: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
        if (body == null || body.length < 2) {
            log.error("VmsResDisplayModuleStatus.process: VMS {}, body length error: {}.", this.vmsObj.getVmsCtlrNmbr(), body != null ? body.length : 0);
            return false;
        }

        // Byte.toUnsignedInt(
        ByteBuffer byteBuffer = ByteBuffer.wrap(body);
        byteBuffer.order(VmsDleFramePacket.BYTE_ORDER);
        this.x = byteBuffer.get(0) & 0xFF;
        this.y = byteBuffer.get(1) & 0xFF;
        if (this.x <= 0 || this.y <= 0) {
            log.error("VmsResDisplayModuleStatus.process: VMS {}, Module Count Error {}/{}.", this.vmsObj.getVmsCtlrNmbr(), this.x, this.y);
            return false;
        }
        if (body.length < ((this.x * this.y) + 2)) {
            log.error("VmsResDisplayModuleStatus.process: VMS {}, Module Count and Body Length Error {}/{}, {}.", this.vmsObj.getVmsCtlrNmbr(), this.x, this.y, body.length);
            return false;
        }

        int idx = 2;
        StringBuilder data = new StringBuilder();
        for (int ii = 0; ii < this.y; ii++) {
            for (int jj = 0; jj < this.x; jj++) {
                byte status = (byte) (byteBuffer.get(idx++) & 0xFF);
                if (status == (byte)0x00) {
                    data.append("1");   // ON
                }
                else if (status == (byte)0x01) {
                    data.append("0");   // OFF
                }
                else {
                    data.append("9");   // 0x02, Unknown
                }
            }
        }
        this.stts = data.toString();

        log.info("{}", toString());

        this.vmsObj.getStts().updateModuleStts(this.stts);

        // 제어기 파라미터 정보 요청
        return this.vmsObj.addRequestData(new TcpServerSendData(eVmsOpCode.OP_VMS_PARAMETER_REQ, null));
    }

    public String toString() {
        StringBuilder data = new StringBuilder();
        data.append(String.format("RESPONSE-%s. VMS %d", eVmsOpCode.OP_VMS_DISPLAY_MODULE_STATUS_REQ, this.vmsObj.getVmsCtlrNmbr()));
        data.append(System.getProperty("line.separator"));
        data.append(String.format("Display Modules (X: %d, Y: %d)", this.x, this.y));
        for (int ii = 0; ii < this.y; ii++) {
            data.append(System.getProperty("line.separator")).append(String.format("Y(%02d): %s", ii, this.stts.substring(ii * this.x, (ii * this.x) + this.x)));
        }
        return data.toString();
    }

}
