package com.zd.laboratory.utils;

import com.zd.common.core.utils.ReUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class HexUtils {
    //包头一
    private static final String  HEAD_ONE="FF";
    //包头二
    private static final String  HEAD_TWO="FF";
    //位置模式控制转动指令包数据长度
    private static final String  COMMAND_LENGTH="09";
    //写指令
    private static final String  WRITE_COMMAND="03";
    //位置模式控制转动指令写入首地址
    private static final String  WRITE_FIRST="2A";
    //位置模式控制转动指令总数
    private static final int COMMAND_SUM=54;
    //读位置指令指令总数
    private static final int READER_COMMAND_SUM=6;
    //读指令
    private static final String READER_COMMAND="02";
    //读位置指令长度
    private static final String READER_COMMAND_LENGTH="04";
    //读首地址
    private static final String READ_WRITE_FIRST="56";
    //读字节数
    private static final String READ_BYTE_NUM="2";

    /**
     * 解密后的卡号需要高低位转换(不足4位前面补0)
     * 才能得到需要的16进制卡号
     * @param serialNum
     * @return
     */
    public static String getHexCardNum(String serialNum,int num) {
        return reverse(hex(Integer.parseInt(serialNum),num));
    }

    /**
     * 10进制转16进制
     * @param serialNum
     * @return
     */
    public static String hex(int serialNum,int num) {
        return  String.format("%0"+num+"x", Integer.valueOf(serialNum));
    }

    /**
     * 十六进制字符串高低位转换
     * @param hex
     * @return
     */
    public static String reverse( String hex) {
        final char[] charArray = hex.toCharArray();
        final int length = charArray.length;
        final int times = length / 2;
        for (int c1i = 0; c1i < times; c1i += 2) {
            final int c2i = c1i + 1;
            final char c1 = charArray[c1i];
            final char c2 = charArray[c2i];
            final int c3i = length - c1i - 2;
            final int c4i = length - c1i - 1;
            charArray[c1i] = charArray[c3i];
            charArray[c2i] = charArray[c4i];
            charArray[c3i] = c1;
            charArray[c4i] = c2;
        }
        return new String(charArray).toUpperCase();
    }

    //10进制转成16进制数
    public static String encodeHEX(Integer numb) {
        String hex = Integer.toHexString(numb);
        return hex;
    }

    //16进制数转成10进制
    public static Integer hexToInteger(String hex) {
        Integer num = Integer.parseInt(hex, 16);
        return num;
    }

    public static List<String> getFileName(String path) {
        List<String> list=new ArrayList<>();
        File f = new File(path);//获取路径  F:测试目录
        if (!f.exists()) {
            System.out.println(path + " not exists");//不存在就输出
            return null;
        }
        File fa[] = f.listFiles();//用数组接收  F:笔记总结C#, F:笔记总结if语句.txt
        for (int i = 0; i < fa.length; i++) {//循环遍历
            File fs = fa[i];//获取数组中的第i个
            if (fs.isDirectory()) {
                System.out.println(fs.getName() + " [目录]");//如果是目录就输出
            } else {
                System.out.println(fs.getName());//否则直接输出
            }
            list.add(fs.getName());
        }
        return list;
    }


    /**
     * 将数字字符串转化为二进制byte数组
     * @param hex
     * @return
     */
    public static byte[] hexStringToByte(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }
        return result;
    }

    private static byte toByte(char c) {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }
    /**
     * 将二进制数组转化为16进制字符串
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            //stringBuilder.append(i + ":");//序号 2个数字为1组
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    private static String hextoString(String javaStr){
        byte [] bytes = hexStringToByte(javaStr);
        byte temp;
        for(int i=0;i<bytes.length;i++){
            temp = bytes[i];
            bytes[i] = (byte) (~temp);
        }
        String bths =  bytesToHexString(bytes);
        return bths.toUpperCase();
    }

    /**
     * 写指令
     * @param position
     * @param time
     * @param speed
     * @return
     */
    public static byte[] generateCommand(String id, String position, String time, String speed){
        StringBuilder stb=new StringBuilder();
        //包头一
        stb.append(HEAD_ONE);
        //包头二
        stb.append(HEAD_TWO);
        int intId=Integer.valueOf(id);
        String hexId=getHexCardNum(id,2);
        //ID号
        stb.append(hexId);
        //指令包数据长度
        stb.append(COMMAND_LENGTH);
        //指令
        stb.append(WRITE_COMMAND);
        //写入首地址
        stb.append(WRITE_FIRST);
        //位置高低字节
        String parsePosition=HexUtils.getHexCardNum(position,4);
        int highPositionInt=hexToInteger(parsePosition.substring(0,2));
        stb.append(parsePosition.substring(0,2));
        int lowPositionInt=hexToInteger(parsePosition.substring(2,4));
        stb.append(parsePosition.substring(2,4));
        //时间高低字节
        String parseTime=HexUtils.getHexCardNum(time,4);
        int highTimeInt=hexToInteger(parseTime.substring(0,2));
        stb.append(parseTime.substring(0,2));
        int lowTimeInt=hexToInteger(parseTime.substring(2,4));
        stb.append(parseTime.substring(2,4));
        //速度高低字节
        String parseSpeed=HexUtils.getHexCardNum(speed,4);
        int highSpeedInt=hexToInteger(parseSpeed.substring(0,2));
        stb.append(parseSpeed.substring(0,2));
        int lowSpeedInt=hexToInteger(parseSpeed.substring(2,4));
        stb.append(parseSpeed.substring(2,4));

        int sum=highPositionInt+lowPositionInt+highTimeInt+lowTimeInt+highSpeedInt+lowSpeedInt+intId+COMMAND_SUM;
        String abc= getHexCardNum(String.valueOf(sum),4);
        String javaStr=abc.substring(0,2);
        stb.append(hextoString(javaStr));
        System.out.println(stb.toString());

        return ReUtil.hexStringToByteArray(stb.toString());
//        return stb.toString().getBytes(StandardCharsets.UTF_8);
    }

    /**
     *读当前位置指令
     * @param id
     * @param head
     * @param byteNum
     * @return
     */
    public static String readCommand(String id,String head,String byteNum){
        StringBuilder stb=new StringBuilder();
        //包头一
        stb.append(HEAD_ONE);
        //包头二
        stb.append(HEAD_TWO);
        int intId=Integer.valueOf(id);
        String hexId=getHexCardNum(id,2);
        //ID号
        stb.append(hexId);
        //指令包数据长度
        stb.append(READER_COMMAND_LENGTH);
        //指令
        stb.append(READER_COMMAND);
        //写入首地址
        String headerPosition=HexUtils.getHexCardNum(head,2);
        stb.append(headerPosition);
        //字节数
        String byteNumHex=HexUtils.getHexCardNum(byteNum,2);
        stb.append(byteNumHex);
        int sum=Integer.parseInt(id)+Integer.parseInt(head)+Integer.parseInt(byteNum)+READER_COMMAND_SUM;
        String abc= getHexCardNum(String.valueOf(sum),4);
        String javaStr=abc.substring(0,2);
        stb.append(hextoString(javaStr));
        System.out.println(stb.toString());
        return stb.toString();
    }

    /**
     *读当前位置指令
     * @param id
     * @return
     */
    public static byte[] readCommandById(String id){
        StringBuilder stb=new StringBuilder();
        //包头一
        stb.append(HEAD_ONE+" ");
        //包头二
        stb.append(HEAD_TWO+" ");
        int intId=Integer.valueOf(id);
        String hexId=getHexCardNum(id,2);
        //ID号
        stb.append(hexId+" ");
        //指令包数据长度
        stb.append(READER_COMMAND_LENGTH+" ");
        //指令
        stb.append(READER_COMMAND+" ");
        //写入首地址
        String headerPosition=HexUtils.getHexCardNum(READ_WRITE_FIRST,2);
        stb.append(headerPosition+" ");
        //字节数
        String byteNumHex=HexUtils.getHexCardNum(READ_BYTE_NUM,2);
        stb.append(byteNumHex+" ");
        int sum=Integer.parseInt(id)+Integer.parseInt(READ_WRITE_FIRST)+Integer.parseInt(READ_BYTE_NUM)+READER_COMMAND_SUM;
        String abc= getHexCardNum(String.valueOf(sum),4);
        String javaStr=abc.substring(0,2);
        stb.append(hextoString(javaStr));
        System.out.println(stb.toString());
        return ReUtil.hexStringToByteArray(stb.toString());
    }

}
