package com.mvc.netty.dealconstant;

import com.mvc.utils.NumberUtil;
import com.mvc.utils.StringUtil;

import java.util.ArrayList;
import java.util.List;

public enum UpgradeIdentifier {
    FF08("FF08", "设备sn", "[a-zA-Z0-9]*"),
    FF16("FF16", "软件版本", "[a-zA-Z0-9]*"),
    FF40("FF40", "任务类型", "[a-zA-Z0-9]*"),
    FF42("FF42", "MCU软件名称", "[a-zA-Z0-9]*"),
    FF43("FF43", "bin镜像校验类型(1:sha256;2:md5;3:CRC)", "[a-zA-Z0-9]*"),
    FF44("FF44", "bin镜像校验1", "[a-zA-Z0-9]*"),
    FF45("FF45", "bin镜像校验2", "[a-zA-Z0-9]*")

    ;

    UpgradeIdentifier(String key, String desc, String rule) {
        this.key = key;
        this.desc = desc;
        this.rule = rule;
    }

    private String key;
    private String desc;
    private String rule;
    private String value;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public String getRule() {
        return rule;
    }

    public void setRule(String rule) {
        this.rule = rule;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    /**
     * 获取key集合
     *
     * @return
     */
    public static List<String> keys() {
        List<String> keyList = new ArrayList<>();
        for (UpgradeIdentifier msg : UpgradeIdentifier.values()) {
            keyList.add(msg.key);
        }
        return keyList;
    }

    /**
     * 解析报文
     *
     * @param msg
     * @return
     */
    public String parse(String msg) {
        String result = msg;
        StringBuilder stringBuilder = new StringBuilder();
        String key = this.key;
        result = handleIdentifier(result);
        String deinfer = result.substring(0, 2);
        result = result.substring(2);
        String binaryStr = NumberUtil.hexStringToBinaryString(deinfer);
        //确定小数位
        String redixStr = binaryStr.substring(binaryStr.length() - 3);
        int radix = NumberUtil.binaryToDecimal(redixStr);
        // 确定数字位数
        String numStr = binaryStr.substring(0, binaryStr.length() - 3);
        int num = NumberUtil.binaryToDecimal(numStr);
        String dataStr = result.substring(0, num * 2);
        if (key.equals("FF01") && dataStr.substring(0, 2).equals("ff")) {
            //取得实践数字字符串
            dataStr = getFactData(dataStr.substring(2));
            result = result.substring(dataStr.length() + 2);
            stringBuilder.append("-" + dataStr);
            if (radix != 0) {
                stringBuilder.insert(dataStr.length() + 1 - radix, '.');
            }
            this.value = stringBuilder.toString();
            return result;
        } else {
            //取得实践数字字符串
            /** 记一个特殊情况,部分设备传FF14时,长度表示符是18(3字节),是错误的,实际是2个字节,但由于getFactData中使用正则进行处理,将下一个引导符FF过滤了,反而变成了2字符
             * 导致看起来是正确的,暂时不作调整 2024-04-12 guozhao
             */
            dataStr = getFactData(dataStr);
            result = result.substring(dataStr.length());
            stringBuilder.append(dataStr);
            if (radix != 0) {
                stringBuilder.insert(dataStr.length() - radix, '.');
            }
            this.value = stringBuilder.toString();
            return result;
        }
    }

    /**
     * 处理表示符
     *
     * @param msg
     * @return
     */
    public String handleIdentifier(String msg) {
        String result = msg;
        result = result.substring(this.key.length());
        return result;
    }

    /**
     * 取得实践数字字符串
     *
     * @param data
     * @return
     */
    private String getFactData(String data) {
        String result = data;
        if (!StringUtil.regularCheck(result, this.rule)) {
            result = data.substring(0, data.length() - 2);
            result = getFactData(result);
        }
        return result;
    }

    /**
     * 获取成员
     *
     * @param key
     * @return
     */
    public static UpgradeIdentifier getElement(String key) {
        for (UpgradeIdentifier msg : UpgradeIdentifier.values()) {
            if (msg.key.equals(key)) {
                return msg;
            }
        }
        return null;
    }
}
