package com.zd.laboratory.socket.service.impl;


import com.zd.laboratory.socket.constant.JXCTPacket;
import com.zd.laboratory.socket.exception.AnalysisException;
import com.zd.laboratory.socket.service.BaseRouter;
import com.zd.laboratory.socket.util.SocketUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * @author liubo
 */
@Service
public class TaskResult implements BaseRouter {

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

    public TaskResult() {
        routerMap.put("02", this);
    }

    @Override
    public String routePacket(JXCTPacket tracketPacket) throws AnalysisException {

        //0x00配置指令字，1字节，固定为
        //0x02问询指令字，1字节，-问询，若命令序号为48，则会返回所有存储的指令，届时将返回48条数据
        String command = tracketPacket.body.substring(0, 2);
        //            命令序号，1字节，（0-47），为48则代表所有存储数据
        String indexHex = tracketPacket.body.substring(2, 4);
        int index = Integer.parseInt(indexHex, 16);
        if ("00".equals(command)) {//配置保存返回
            //继电器位号，2字节，0x03ff=0b001111111111，按位表示继电器状态，最低位表示第1号继电器，此时置1表示该位继电器当前打开，置0表示该位继电器当前关闭
            String bitHex = tracketPacket.body.substring(4, 8);
            String bit = SocketUtils.getHexBit(bitHex, 16);
            log.info(tracketPacket.deviceNumber + "定时任务配置指令返回：command：" + command + "  index:" + index + "  bitHex:" + bitHex + " bit:" + bit);
            //添加问问询
            tracketPacket.order = "02";
            tracketPacket.body = "02" + indexHex;
            log.info(tracketPacket.toString());
            return tracketPacket.encodeString();
        } else if ("01".equals(command)) {//清空返回指令字，1字节，0x01-清空，会将保存的指令全置为0x3F
            //继电器位号，2字节，0x03ff=0b001111111111，按位表示继电器状态，最低位表示第1号继电器，此时置1表示该位继电器当前打开，置0表示该位继电器当前关闭
            String bitHex = tracketPacket.body.substring(4, 8);
            String bit = SocketUtils.getHexBit(bitHex, 16);
            log.info(tracketPacket.deviceNumber + "清空指令返回：" + index + "  bitHex:" + bitHex + " bit:" + bit);
        } else if ("02".equals(command)) {//问询返回
//            继电器位号，2字节，用以选中继电器

            //继电器控制字节，1字节，0x70=0b01110000，
            //由高位到低位，
            //开启时间执行的：
            //高两位-动作控制位，开启/关闭/取反（u2）（00-关闭，01-开启，10-取反）
            //第3位-联动控制位，（0-有效，1-无效）
            //第4位-互斥控制位，（0-有效，1-无效）（逻辑冲突时，返回一条错误信息，不执行互斥操作）
            //后四位无意义
            String control = tracketPacket.body.substring(8, 10);
            String controlBit = Integer.toBinaryString(Integer.parseInt(control, 16));

            //日期支持以字符’*’实现通配，故要求输入为ascii值
            //开始动作的日期，年，2字节，年份的千位固定为2，百位固定为0，要求输入年份的十位和个位值，要求为ascii值，如0x32,0x30,即分别为字符’2’，’0’，代表2020年
            String startYear = new String(SocketUtils.str2byte(tracketPacket.body.substring(10, 14)));

            //开始动作的日期，月，2字节，ascii值，如0x30，0x32，分别为字符’0’，’2’，即为02月
            String startMonth = new String(SocketUtils.str2byte(tracketPacket.body.substring(14, 18)));

            //开始动作的日期，日，2字节，ascii值，如0x31，0x38，分别为字符’1’，’8’，即为18日
            String startDay = new String(SocketUtils.str2byte(tracketPacket.body.substring(18, 22)));

            //开始动作的日期，时，2字节，ascii值，如0x2a，0x36，分别为字符’*’，’8’，即代表当小时的个位为8，十位为任意数值时，都执行指令，此即为通配
            String startHour = new String(SocketUtils.str2byte(tracketPacket.body.substring(22, 26)));

            //开始动作的日期，分，2字节，ascii值，如0x34，0x35，分别为字符’4’，’5’，即为45分
            String startMinute = new String(SocketUtils.str2byte(tracketPacket.body.substring(26, 30)));

            //开始动作的日期，秒，2字节，ascii值，如0x2a，0x2a，分别为字符’*’，’*’，即为在秒数十位为任意值，各位为任意值时，执行指令
            String startSeconds = new String(SocketUtils.str2byte(tracketPacket.body.substring(30, 34)));

            //开始动作的日期，周几，1字节，ascii值，如0x31，为字符’1’，即为周一
            String startWeeks = new String(SocketUtils.str2byte(tracketPacket.body.substring(34, 36)));

            //结束动作的日期，年，2字节
            String endYear = new String(SocketUtils.str2byte(tracketPacket.body.substring(36, 40)));

            //结束动作的日期，月，2字节
            String endMonth = new String(SocketUtils.str2byte(tracketPacket.body.substring(40, 44)));

            //结束动作的日期，日，2字节
            String endDay = new String(SocketUtils.str2byte(tracketPacket.body.substring(44, 48)));

            //结束动作的日期，时，2字节
            String endHour = new String(SocketUtils.str2byte(tracketPacket.body.substring(48, 52)));

            //结束动作的日期，分，2字节
            String endMinute = new String(SocketUtils.str2byte(tracketPacket.body.substring(52, 56)));

            //结束动作的日期，秒，2字节
            String endSeconds = new String(SocketUtils.str2byte(tracketPacket.body.substring(56, 60)));

            //结束动作的日期，周几，1字节
            String endWeeks = new String(SocketUtils.str2byte(tracketPacket.body.substring(60, 62)));

            log.info("index:" + index + " controlBit:" + controlBit);
            log.info("动作开始时间：" + startYear + "/" + startMonth + "/" + startDay + " " + startHour + ":" + startMinute + ":" + startSeconds + " 周：" + startWeeks);
            log.info("动作结束时间：" + endYear + "/" + endMonth + "/" + endDay + " " + endHour + ":" + endMinute + ":" + endSeconds + " 周：" + endWeeks);

        } else if ("03".equals(command)) {//指令使能控制返回
            log.info(tracketPacket.deviceNumber + "  " + command + "  指令使能控制返回");
//            指令执行标志，1字节，
//            0-操作失败
//            1-操作成功
            //结果
            String result = indexHex;//tracketPacket.body.substring(2, 4);
            if ("00".equals(result)) {
                log.info(tracketPacket.deviceNumber + "  " + command + "  指令使能控制返回 00-操作成功");
            } else if ("01".equals(result)) {
                log.info(tracketPacket.deviceNumber + "  " + command + "  指令使能控制返回 01-操作失败");
            } else {
                log.info(tracketPacket.deviceNumber + "  " + command + "  指令使能控制返回 其他标志:" + result);
            }
//            //指令使能位，6个字节，共48位，最低位代表第一条指令的控制位，置1表示该条指令使能，置0表示失能，即不执行
        } else if ("04".equals(command)) {//指令使能状态问询
            //指令使能位，6个字节，共48位，最低位代表第一条指令的控制位，置1表示该条指令使能，置0表示失能，即不执行
            String enable = tracketPacket.body.substring(8, 20);
            String enableBit = Integer.toBinaryString(Integer.parseInt(enable, 16));
            log.info("指令使能状态:" + enable + "  bit:" + enableBit);
        } else {
            log.info("其他指令：" + command);
        }
        return null;
    }
}
