package com.zd.laboratory.socket.command;

import com.zd.laboratory.socket.constant.JXCTPacket;
import com.zd.laboratory.socket.runner.TCPServer;
import com.zd.laboratory.socket.util.SocketUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @author  liubo
 */
public class Control {

    private static final Logger log = LoggerFactory.getLogger(Control.class);

    /**
     *  继电器 控制总入口
     * @param order 操作指令
     * @param deviceNumber 继电器编码
     * @param command 控制指令 开启/关闭
     * @param lines 继电器线路数量 从1 开始，不能大于该继电器的总数  最大16
     */
    public static String sendCommand(@NotNull Symbol.order order, @NotNull String deviceNumber, @NotNull Symbol.command command, int lines) {
        //下发继电器控制
        if (Symbol.order.control.equals(order)) {
            if (lines < 1 || lines > 16) {
                return "继电器数量超出范围！";
            }
            try {
                return sendRelayCommand(deviceNumber, lines - 1, Integer.parseInt(command.getType()));
            } catch (Exception e) {
                return "指令错误：" + e.toString();
            }
        }
        return "未识别指令";

    }
    /**
     *  继电器 控制总入口
     * @param order 操作指令
     * @param deviceNumber 继电器编码
     * @param command 控制指令 开启/关闭
     * @param lines 继电器线路数量 从1 开始，不能大于该继电器的总数  最大16
     */
    public static String sendCommand(@NotNull Symbol.order order, @NotNull String deviceNumber, @NotNull String command, int lines) {
        //下发继电器控制
        if (Symbol.order.control.equals(order)) {
            if (lines < 1 || lines > 16) {
                return "继电器数量超出范围！";
            }
            try {
                return sendRelayCommand(deviceNumber, lines - 1, Integer.parseInt(command));
            } catch (Exception e) {
                return "指令错误：" + e.toString();
            }
        }
        return "未识别指令";

    }
    /**
     * 下发继电器控制
     *
     * @param deviceNumber 设备号，第一个字节表示继电器位数，16进制
     * @param bit          第几路继电器，从0开始
     * @param state        开关状态，0关  1开
     */
    private static String sendRelayCommand(String deviceNumber, int bit, int state) {
        if (deviceNumber == null || deviceNumber.length() != 12) {
            return "设备号错误";
        }
        //继电器路数
        int relayCount = Integer.parseInt(deviceNumber.substring(0, 2), 16);
        if (bit > (relayCount - 1) || state > 1 || state < 0) {
            return "指令错误";
        }
        OutputStream ops = TCPServer.cacheMap.get(deviceNumber);
        if (ops == null) {
            return "设备不在线";
        }
        //控制位
        StringBuilder bitBuilder = new StringBuilder();
        for (int i = 0; i < relayCount; i++) {
            if (bit == i) {
                bitBuilder.append(1);
            } else {
                bitBuilder.append(0);
            }
        }
        bitBuilder.reverse();

        //下发指令（—继电器控制字节-）
        StringBuilder hexBuilder = new StringBuilder(SocketUtils.getHexString(Integer.parseInt(bitBuilder.toString(), 2), 4));
        if (state == 0) {
            // 关闭
            hexBuilder.append("38");
        } else {
            // 开启
            hexBuilder.append("78");
        }
        JXCTPacket packet = new JXCTPacket();
        packet.deviceNumber = deviceNumber;
        packet.order = "01";
        packet.body = hexBuilder.toString();
        log.info(deviceNumber + " 下发控制：" + bitBuilder + "  hex:" + packet.toString());
        byte[] sendBody = packet.encode();
        try {
            ops.write(sendBody);
        } catch (IOException e) {
            log.error("下发失败：" + e.toString());
            TCPServer.cacheMap.remove(deviceNumber);
            return "下发失败, 连接中断";
        }
        return "下发成功";
    }

}
