package com.tsi.comm.server.protocol;

import com.tsi.comm.server.protocol.enums.eOpCode;
import com.tsi.comm.server.vo.TsiNodeAddDetailVo;
import com.tsi.comm.server.vo.TsiNodeAddVo;
import com.tsi.comm.server.vo.TsiNodeVo;
import com.tsi.common.utils.ByteUtils;
import com.tsi.common.utils.TimeUtils;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;

import static com.tsi.comm.server.protocol.TsiCvibProtocolSpec.*;

@Getter
@Setter
public class TsiCpuDisconnected extends TsiCpuPacket {

    public TsiCpuDisconnected(long nodeId, long remoteIpAddress, int remotePort) {
        super(nodeId, TimeUtils.currentTimeSeconds(), System.nanoTime(), remoteIpAddress, remotePort);
        setOpCode(eOpCode.TSI_CPU_DISCONNECTED.getValue());
    }

    protected void makeAddNodeCvimPaket(TsiCpuPacket cpuPacket) {
        cpuPacket.cvimData = new byte[SIZE_IPC_SIZE];   // ipc head only

        // cvim-raw header
        System.arraycopy(this.timespec.bytes(), 0, cpuPacket.cvimData, POS_IPC_TIMESPEC, SIZE_TIMESPEC);
        ByteUtils.setUnsignedInt(cpuPacket.cvimData, POS_IPC_IPADDR, getRemoteIp());
        ByteUtils.setUnsignedShort(cpuPacket.cvimData, POS_IPC_PORT, getRemotePort());
        cpuPacket.cvimData[POS_IPC_CONNECT] = DISCONNECT;
        ByteUtils.setUnsignedInt(cpuPacket.cvimData, POS_IPC_NODEID, cpuPacket.nodeId);
    }

    public boolean parsing(TsiNodeVo nodeVo) {

        if (nodeVo == null) {
            return false;
        }

        // CVIM DATA 생성
        makeCvimPacket();

        TsiNodeAddVo tsiNodeAddVo = TsiCpuPacket.nodeAddManager.get(this.nodeId);
        if (tsiNodeAddVo == null) {
            // 연등지 정보가 없는 경우
            return true;
        }

        // 연등지 노드 카프카 패킷 생성
        this.addNodes = new ArrayList<>();

        for (Integer key : tsiNodeAddVo.getAddNodeMap().keySet()){
            TsiNodeAddDetailVo detailVo = tsiNodeAddVo.getAddNodeMap().get(key);
            TsiCpuAddPacket addPacket = new TsiCpuAddPacket(detailVo.getNodeId(), this.timespec, this.remoteIp, this.remotePort);
            makeAddNodeCvimPaket(addPacket);

            // 연등지 노드에 연결종료 메시지 생성
            this.addNodes.add(addPacket);
        }
        return true;
    }

}
