package com.ruoyi.sim.service.impl;

import com.ruoyi.sim.domain.SimMsg;
import com.ruoyi.sim.util.CRC16Modbus;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static com.ruoyi.sim.service.impl.CommConst.*;

@Service
public class CommBuildService {

    private static final Logger l = LoggerFactory.getLogger(CommBuildService.class);
    /**
     * CRC-16(Modbus)
     * <p>
     * https://www.23bei.com/tool/59.html
     */
    public static boolean CRC_16_MODBUS = true;

    @Autowired
    private SnowflakeIdService idService;

    /**
     * 设备类型读取
     *
     * @param simNum sim.sim_num
     */
    public SimMsg buildSendMsgReadSimType(final String simNum) {
        return buildSendMsg(simNum, CMD_READ_TYPE, CMD_ID_GET_SN);
    }

    /**
     * 故障下发
     *
     * @param simNum          sim.sim_num
     * @param bindHardwareMsg fault.bind_hardware_msg
     */
    public SimMsg buildSendMsgWriteFault(final String simNum, final String bindHardwareMsg) {
        return buildSendMsg(simNum, CommConst.CMD_SET_FAULT, bindHardwareMsg);
    }

    /**
     * 状态读取
     *
     * @param simNum          sim.sim_num
     * @param bindHardwareMsg fault.bind_hardware_msg
     */
    public SimMsg buildSendMsgReadFaultResistance(final String simNum, final String bindHardwareMsg) {
        return buildSendMsg(simNum, CMD_READ_FAULT_RESISTANCE, bindHardwareMsg);
    }

    /**
     * 故障清清除
     *
     * @param simNum          sim.sim_num
     * @param bindHardwareMsg fault.bind_hardware_msg
     */
    public SimMsg buildSendMsgClearFault(final String simNum, final String bindHardwareMsg) {
        return buildSendMsg(simNum, CMD_CLEAR_FAULT, bindHardwareMsg);
    }

    public SimMsg buildSendMsg(final String simNum, final String cmd, final String cmdId) {
        return buildSendMsg(simNum, cmd, cmdId, CMD_DATA_PLACE_HOLDER);
    }

    public SimMsg buildSendMsg(final String simNum, final String cmd, final String cmdId, final String data) {
        SimMsg smS = new SimMsg();
        smS.setSimMsgId(idService.nextId());
        if (StringUtils.isEmpty(simNum) || StringUtils.isEmpty(cmd) || StringUtils.isEmpty(cmdId) || StringUtils.isEmpty(data)) {
            throw new IllegalArgumentException("buildSendMsg error 01");
        }
        if (simNum.length() != LENGTH_2) {
            throw new IllegalArgumentException("buildSendMsg error 02");
        }
        if (cmd.length() != LENGTH_2) {
            throw new IllegalArgumentException("buildSendMsg error 03");
        }
        if (cmdId.length() != LENGTH_2) {
            throw new IllegalArgumentException("buildSendMsg error 04");
        }
        if (data.length() != LENGTH_8) {
            throw new IllegalArgumentException("buildSendMsg error 05");
        }
        StringBuffer m = new StringBuffer();
        m.append(PREFIX);
        m.append(simNum);
        m.append(ORN_SEND);
        m.append(cmd);
        m.append(cmdId);
        m.append(data);
        // 追加CRC校验
        if (CRC_16_MODBUS) {
            String crcContent = m.toString();
            byte[] sendByteContent = CommSendService.hexStrToByteArrs(crcContent);
            // l.info("sendByteContent = {}", CommSendService.bytesToHexV2(sendByteContent));
            byte[] sendByteCrc = CRC16Modbus.calculateCRC(sendByteContent);
            // l.info("sendByteCrc = {}", CommSendService.bytesToHexV2(sendByteCrc));
            String crc = CommSendService.bytesToHexV2(sendByteCrc);
            // l.debug("crc: {}", crc.toUpperCase());
            m.append(crc.toUpperCase());
        }
        m.append(SUFFIX);
        final String mFinal = m.toString();
        if (mFinal.length() != LENGTH_24) {
            throw new IllegalArgumentException("buildSendMsg error 06");
        }
        smS.setSendMsg(mFinal);
        return smS;
    }

    /**
     * check receiveMsg
     *
     * @param receiveMsg
     * @return
     */
    public boolean checkReceiveMsg(String receiveMsg) {
        // 不能是empty
        if (StringUtils.isEmpty(receiveMsg)) {
            return false;
        }
        // 长度
        if (receiveMsg.length() != LENGTH_24) {
            return false;
        }
        // 数据方向
        final String orn = StringUtils.substring(receiveMsg, 4, 6);
        if (!ORN_RECEIVE.equals(orn)) {
            return false;
        }
        // 前缀
        if (!StringUtils.startsWith(receiveMsg, PREFIX)) {
            return false;
        }
        // 后缀
        if (!StringUtils.endsWith(receiveMsg, SUFFIX)) {
            return false;
        }
        // 计算CRC16
        if (false) {
            String crcContent = receiveMsg.substring(0, 18);
            l.debug("crcContent: {}", crcContent.toUpperCase());
            byte[] receiveByteContent = CommSendService.hexStrToByteArrs(crcContent);
            byte[] receiveByteCrc = CRC16Modbus.calculateCRC(receiveByteContent);
            String crc = CommSendService.bytesToHexV2(receiveByteCrc);
            l.debug("crc: {}", crc.toUpperCase());
//            if (!receiveMsg.substring(19, 22).equals(crc.toUpperCase())) {
//                throw new IllegalArgumentException("checkReceiveMsg length error");
//            }

            // todo: 比对校验值，不正确。
        }
        return true;
    }
}
