package com.ruoyi.sim.service.my;

import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import static com.ruoyi.sim.service.my.IotService.Const.*;

/**
 * 硬件通信
 */
@Service
public class IotService {

    interface Const {

        String IP = "127.0.0.1";
        int PORT = 9000;
        /**
         * 报文长度
         */
        int MSG_LENGTH = 20;

        String PREFIX = "AA";

        String SUFFIX = "55";

        /**
         * orientation
         */
        String ORN_SEND = "01";

        /**
         * orientation
         */
        String ORN_RECEIVE = "02";

        String CMD_DATA_PLACE_HOLDER = "00000000";

        String CMD_READ = "03";

        String CMD_GET_SIM_TYPE = "B1";

        String CMD_SET_FAULT = "01";

        String CMD_READ_SIM_FAULT_STATE = "03";

        String CMD_CLEAR_SIM_FAULT = "02";
    }

    private static final Logger logger = LoggerFactory.getLogger(IotService.class);

    private Socket socket = null;

    /**
     * 检查所有模拟器状态
     */
    public void checkAllSim() {

    }

    /**
     * 设备类型读取
     *
     * @param simNum 设备编号
     */
    public void getSimType(final String simNum) {
        // todo:check

        //
        StringBuffer m = new StringBuffer();
        m.append(PREFIX);
        m.append(simNum);
        m.append(ORN_SEND);
        m.append(CMD_READ);
        m.append(CMD_GET_SIM_TYPE);
        m.append(CMD_DATA_PLACE_HOLDER);
        m.append(SUFFIX);
        final String sendMsg = m.toString();
        final String receiveMsg = send(sendMsg);
    }

    /**
     * 故障下发
     *
     * @param simNum    设备编号
     * @param faultType 故障类型
     */
    public void setFault(final String simNum, final String faultType) {
        // todo:check

        //
        StringBuffer m = new StringBuffer();
        m.append(PREFIX);
        m.append(simNum);
        m.append(ORN_SEND);
        m.append(CMD_SET_FAULT);
        m.append(faultType);
        m.append(CMD_DATA_PLACE_HOLDER);
        m.append(SUFFIX);
        //

        //
        final String receiveMsg = send(m.toString());
        //
    }

    /**
     * 状态读取
     *
     * @param simNum    设备编号
     * @param faultType 故障类型
     */
    public void getSimStatus(final String simNum, final String faultType) {
        // todo:check

        //
        StringBuffer m = new StringBuffer();
        m.append(PREFIX);
        m.append(simNum);
        m.append(ORN_SEND);
        m.append(CMD_READ_SIM_FAULT_STATE);
        m.append(faultType);
        m.append(CMD_DATA_PLACE_HOLDER);
        m.append(SUFFIX);
        //

        //
        final String receiveMsg = send(m.toString());
        //
    }

    /**
     * 故障清清除
     *
     * @param simNum    设备编号
     * @param faultType 故障类型
     */
    public void clearSimStatus(final String simNum, final String faultType) {
        // todo:check

        //
        StringBuffer m = new StringBuffer();
        m.append(PREFIX);
        m.append(simNum);
        m.append(ORN_SEND);
        m.append(CMD_CLEAR_SIM_FAULT);
        m.append(faultType);
        m.append(CMD_DATA_PLACE_HOLDER);
        m.append(SUFFIX);
        //

        //
        final String receiveMsg = send(m.toString());
        //
    }

    /**
     * send hex message
     *
     * @param sendMsg
     * @return
     */
    public String send(final String sendMsg) {
        logger.info("sendMsg");
        logger.info(sendMsg);
        String receiveMsg = null;
        try {
            if (socket == null) {
                socket = new Socket(IP, PORT);
            }
            InputStream is = socket.getInputStream();
            OutputStream os = socket.getOutputStream();
            os.write(hexStrToByteArrs(sendMsg));
            byte[] buffer = new byte[1024];
            int length = is.read(buffer);
            StringBuffer sbHex = new StringBuffer();
            for (int i = 0; i < length; i++) {
                sbHex.append(String.format("%02X", buffer[i]));
            }
            receiveMsg = sbHex.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        logger.info("receiveMsg");
        logger.info(receiveMsg);
        return receiveMsg;
    }

    /**
     *
     */
    public void close() {
        try {
            if (socket != null) {
                socket.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            socket = null;
        }
    }

    public byte[] hexStrToByteArrs(String hexString) {
//        if (StringUtils.isEmpty(hexString)) {
//            return null;
//        }
        hexString = hexString.replaceAll(" ", "");
        int len = hexString.length();
        int index = 0;

        byte[] bytes = new byte[len / 2];

        while (index < len) {
            String sub = hexString.substring(index, index + 2);
            bytes[index / 2] = (byte) Integer.parseInt(sub, 16);
            index += 2;
        }
        return bytes;
    }
}
