/**
 * Copyright 2019 DH
 * All right reserved.
 * 项目名称: 大恒泰山系统
 * 创建日期:2022/2/23
 */
package org.ts.ddcs.common.util;


import java.math.BigDecimal;
import java.util.Calendar;

/***
 * Date:2022/2/23
 * Title: 数据项模板
 * Description：解析数据帮助，公共方法
 * @author dylan
 *
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
public class Sw2014DatagramTemplateHelp {
    private static final String SYMBOL_FLAG = "FF";

    /**
     * 解析数值字节长度及小数位长度
     *
     * @param byteValue
     * @return
     */
    public static ValueLen getValueLen(byte byteValue) {
        int dataTotalLen = byteValue >> 3;
        int decimalLen = byteValue & 7;
        ValueLen valueLen = new ValueLen();
        valueLen.setByteLen(dataTotalLen);
        valueLen.setDecimalLen(decimalLen);
        return valueLen;
    }

    /**
     * 解析数值字节长度及小数位长度
     *
     * @param dataBuff
     * @param pos
     * @return
     */
    public static ValueLen getValueLen(byte[] dataBuff, int pos) {
        byte byteValue = dataBuff[pos];
        int dataTotalLen = byteValue >> 3;
        int decimalLen = byteValue & 7;
        ValueLen valueLen = new ValueLen();
        valueLen.setByteLen(dataTotalLen);
        valueLen.setDecimalLen(decimalLen);
        return valueLen;
    }

    /**
     * 报文体长度
     *
     * @param buff
     * @return
     */
    public static int getContentLen(byte[] buff) {
        byte[] tmpbuf = new byte[2];
        tmpbuf[0] = (byte) (buff[0] & 0x0f);
        tmpbuf[1] = buff[1];
        int v = 0;
        for (int ii = 0; ii < 2; ii++) {
            int shi = (2 - 1 - ii) * 8;
            v += (tmpbuf[ii] & 0x00FF) << shi;
        }
        return v;
    }

    public static BigDecimal getDecimalValue(byte[] buff, int pos) {
        return null;
    }

    /**
     * 解析数字类型数值
     *
     * @param buff
     * @param index
     * @param byteLen
     * @param decimalLen
     * @return
     */
    public static BigDecimal toDecimal(byte[] buff, int index, int byteLen, int decimalLen) {
        String decimalValue = Sw2014DatagramTemplateHelp.toDecimalString(buff, index, byteLen, decimalLen);
        if (null != decimalValue) {
            return new BigDecimal(decimalValue);
        }
        return null;
    }

    /**
     * 解析数字类型数值并转成字符串
     *
     * @param buff
     * @param index
     * @param byteLen
     * @param decimalLen
     * @return
     */
    public static String toDecimalString(byte[] buff, int index, int byteLen, int decimalLen) {
        if (buff.length == 0 || (buff.length - index) < byteLen) {
            return null;
        }
        byte[] valueBuff = BytesUtil.subBytes(buff, index, byteLen);
        if (null == valueBuff || valueBuff.length <= 0) {
            return null;
        }
        String hexStr = BytesUtil.byte2HexStr(valueBuff);
        StringBuffer tmpString = new StringBuffer(hexStr);
        String symbol = "";
        if (SYMBOL_FLAG.equals(hexStr.substring(0, 2))) {
            tmpString = new StringBuffer(hexStr.substring(2));
            symbol = "-";
        }
        if (decimalLen != 0) {
            tmpString.insert(tmpString.length() - decimalLen, ".");
        }
        String decimalValue = StringUtil.getPrettyNumber(tmpString.toString());
        decimalValue = symbol + decimalValue;
        return decimalValue;
    }

    /**
     * 水文规约2014CRC检验
     *
     * @param packet
     * @param pos
     * @param length
     * @return
     */
    public static byte[] crcFun2014(byte[] packet, int pos, int length) {
        int n = length;
        int crc = 0xFFFF;
        for (int b = 0; b < n; b++) {
            crc = BytesHelp.byteToInteger(packet[pos + b]) ^ crc;
            for (int c = 0; c < 8; c++) {
                int dd = crc & 0x0001;
                if (dd == 1) {
                    crc = crc >> 1;
                    crc ^= 0xA001;
                } else {
                    crc = crc >> 1;
                }
            }
        }
        return BytesHelp.int2Bytes(crc, 2);
    }

    /**
     * 水文规约2014CRC检验
     *
     * @param packet
     * @return
     */
    public static byte[] crcFun2014(byte[] packet) {
        int n = packet.length;
        int crc = 0xFFFF;
        for (int b = 0; b < n; b++) {
            crc = BytesHelp.byteToInteger(packet[b]) ^ crc;
            for (int c = 0; c < 8; c++) {
                int dd = crc & 0x0001;
                if (dd == 1) {
                    crc = crc >> 1;
                    crc ^= 0xA001;
                } else {
                    crc = crc >> 1;
                }
            }
        }
        return BytesHelp.int2Bytes(crc, 2);
    }

    /**
     * 流水号
     *
     * @param dataBuff
     * @param pos
     * @return
     */
    public static String toSerialNo(byte[] dataBuff, int pos) {
        int sn = BytesHelp.bytes2Int(dataBuff, pos, 2);
        return Integer.toString(sn);
    }

    /**
     * 发报时间
     * 格式 yyyyMMddHHmmss
     *
     * @param buff
     * @return
     */
    public static String toSendPacketTime(byte[] buff) {
        return "20" + BytesHelp.byte2HexStr(buff);
    }

    /**
     * 发报时间
     * 格式 yyyyMMddHHmmss
     *
     * @param buff
     * @param pos
     * @return
     */
    public static String toSendPacketTime(byte[] buff, int pos) {
        byte[] timeBuff = BytesHelp.subBytes(buff, pos, 6);
        return "20" + BytesHelp.byte2HexStr(timeBuff);
    }

    /**
     * 获取发报时间
     *
     * @return
     */
    public static byte[] getFBTm() {


        Calendar now = Calendar.getInstance();
        String year = now.get(Calendar.YEAR) + "";
        String month = now.get(Calendar.MONTH) + 1 + "";
        String day = now.get(Calendar.DATE) + "";
        String hour = now.get(Calendar.HOUR_OF_DAY) + "";
        String minute = now.get(Calendar.MINUTE) + "";
        String second = now.get(Calendar.SECOND) + "";

        byte[] tpArea;

        tpArea = BytesHelp.hexStr2Bytes(year.substring(2, year.length()));

        if (month.length() == 1) {
            tpArea = BytesHelp.arrayApend(tpArea,
                    BytesHelp.hexStr2Bytes("0" + month));
        } else {
            tpArea = BytesHelp.arrayApend(tpArea,
                    BytesHelp.hexStr2Bytes(month));
        }

        if (day.length() == 1) {
            tpArea = BytesHelp.arrayApend(tpArea,
                    BytesHelp.hexStr2Bytes("0" + day));
        } else {
            tpArea = BytesHelp.arrayApend(tpArea,
                    BytesHelp.hexStr2Bytes(day));
        }
        if (hour.length() == 1) {
            tpArea = BytesHelp.arrayApend(tpArea,
                    BytesHelp.hexStr2Bytes("0" + hour));
        } else {
            tpArea = BytesHelp.arrayApend(tpArea,
                    BytesHelp.hexStr2Bytes(hour));
        }
        if (minute.length() == 1) {
            tpArea = BytesHelp.arrayApend(tpArea,
                    BytesHelp.hexStr2Bytes("0" + minute));
        } else {
            tpArea = BytesHelp.arrayApend(tpArea,
                    BytesHelp.hexStr2Bytes(minute));
        }

        if (second.length() == 1) {
            tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + second));
        } else {
            tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(second));
        }

        return tpArea;

    }

    public BigDecimal readBigDecimal(byte[] dataBuff, int pos) {
        byte len = dataBuff[pos];
        int dataTotalLen = len >> 3;
        int decimalLen = len & 7;
        byte[] buff = BytesHelp.subBytes(dataBuff, pos + 1, dataTotalLen);
        if (BytesHelp.errorValue(buff)) {
            return null;
        }
        BigDecimal v = BytesHelp.toDecimal(buff, decimalLen);
        return v;
    }

    public BigDecimal readBigDecimal(byte[] dataBuff, int pos, int byteLenCheck) {
        byte len = dataBuff[pos];
        int dataTotalLen = len >> 3;
        int decimalLen = len & 7;
        byte[] buff = BytesHelp.subBytes(dataBuff, pos + 1, dataTotalLen);
        if (BytesHelp.errorValue(buff)) {
            return null;
        }
        if ((byte) buff[0] == 0xFF) {
            if (dataTotalLen - 1 != byteLenCheck) {
                return null;
            }
        } else {
            if (dataTotalLen != byteLenCheck) {
                return null;
            }
        }
        BigDecimal v = BytesHelp.toDecimal(buff, decimalLen);
        return v;
    }
}
