package com.imdroid.common.util;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

/**
 * @author Layton
 * @date 2022/3/21 15:36
 */
public class DataTypeUtil {

    public static byte[] intToByteLittle(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        return b;
    }

    public static byte[] intToByteBig(int number) {
        byte[] b = new byte[4];

        b[0] = (byte) (number >> 24);
        b[1] = (byte) (number >> 16);
        b[2] = (byte) (number >> 8);
        b[3] = (byte) number;

        return b;
    }

    public static byte[] floatToByteLittle(float n) {
        int fbit = Float.floatToIntBits(n);
        return intToByteLittle(fbit);
    }

    public static byte[] floatToByteBig(float n) {
        int fbit = Float.floatToIntBits(n);
        return intToByteBig(fbit);
    }

    /**
     * 将byte数组转换为long数据 (大端模式)
     *
     * @param data
     *            length为8的byte数组
     * @return
     */
    public static long byteToLong(byte[] data) {
        ByteBuffer buffer = ByteBuffer.allocate(8);

        buffer.put(data, 0, 8);
        buffer.flip();

        return buffer.getLong();
    }

    /**
     * 将byte数组转换为long数据 (大端模式)
     *
     * @param data
     *            length为8的byte数组
     * @return
     */
    public static long byteToLong(byte[] data, int offset) {
        ByteBuffer buffer = ByteBuffer.allocate(8);

        buffer.put(data, offset, 8);
        buffer.flip();

        return buffer.getLong();
    }

    /**
     * 将byte数组转为int数据 (大端模式)
     *
     * @param data
     *            length为4的byte数组
     * @return
     */
    public static int byteToInt(byte[] data) {
        ByteBuffer buffer = ByteBuffer.allocate(4);

        buffer.put(data, 0, 4);
        buffer.flip();

        return buffer.getInt();
    }

    /**
     * 将byte数组转为int数据 (大端模式)
     *
     * @param data
     *            length为4的byte数组
     * @return
     */
    public static int byteToInt(byte[] data, int offset) {
        ByteBuffer buffer = ByteBuffer.allocate(4);

        buffer.put(data, offset, 4);
        buffer.flip();

        return buffer.getInt();
    }

    /**
     * 将byte数组转为short数据 (大端模式)
     *
     * @param data
     *            length为2的byte数组
     * @return
     */
    public static short byteToShort(byte[] data) {
        ByteBuffer buffer = ByteBuffer.allocate(2);

        buffer.put(data, 0, 2);
        buffer.flip();

        return buffer.getShort();
    }

    /**
     * 将byte数组转为float数据(大端模式)
     *
     * @param data
     *            length为4的byte数组
     * @return
     */
    public static float bytesToFloat(byte[] data) {
        int value = byteToInt(data);
        return Float.intBitsToFloat(value);
    }

    /**
     * 将byte数组转为float数据(小端模式)
     *
     * @param data
     *            length为4的byte数组
     * @return
     */
    public static float lowBytesToFloat(byte[] data) {
        int len = data.length;
        // 获得一个反的数组
        byte[] dest = new byte[len];

        for (int i = 0; i < len; i++) {
            dest[len - i - 1] = data[i];
        }

        int value = byteToInt(dest);
        return Float.intBitsToFloat(value);
    }

    /**
     * byte数组大小端反转
     *
     * @param bytes 数据
     */
    public static void bytesReverse(byte[] bytes) {
        int half = bytes.length / 2;
        for (int i = 0; i < half; i++) {
            byte temp = bytes[i];
            bytes[i] = bytes[bytes.length - i - 1];
            bytes[bytes.length - i - 1] = temp;
        }
    }

    /**
     * 将long转为byte数组 (大端模式)
     *
     * @param number
     * @return
     */
    public static byte[] longToByte(long number) {
        byte[] b = new byte[8];

        b[0] = (byte) (number >> 56);
        b[1] = (byte) (number >> 48);
        b[2] = (byte) (number >> 40);
        b[3] = (byte) (number >> 32);
        b[4] = (byte) (number >> 24);
        b[5] = (byte) (number >> 16);
        b[6] = (byte) (number >> 8);
        b[7] = (byte) number;

        return b;
    }

    /**
     * 将short转为byte数组 (小端模式)
     *
     * @param number
     * @return
     */
    public static byte[] shortToByteLittle(short number) {

        byte[] src = new byte[2];
        src[1] = (byte) ((number >> 8) & 0xFF);
        src[0] = (byte) (number & 0xFF);
        return src;
    }

    /**
     * 将short转为byte数组 (大端模式)
     *
     * @param number
     * @return
     */
    public static byte[] shortToByteBig(short number) {

        byte[] src = new byte[2];
        src[0] = (byte) ((number >> 8) & 0xFF);
        src[1] = (byte) (number & 0xFF);
        return src;
    }


    public static short byteToShort(byte byte0, byte byte1) {
        return (short) (((byte0 & 0xff) << 8) | (byte1 & 0xff));
    }

    /**
     * 将byte转换为一个长度为8的byte数组，数组每个值代表bit
     *
     * @param b
     * @return
     */
    public static byte[] getBitArray(byte b) {
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >> 1);
        }
        return array;
    }

    /**
     * 把byte转为字符串的bit
     *
     * @param b
     * @return
     */
    public static String byteToBit(byte b) {
        return ""
                + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1)
                + (byte) ((b >> 5) & 0x1) + (byte) ((b >> 4) & 0x1)
                + (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1)
                + (byte) ((b >> 1) & 0x1) + (byte) ((b >> 0) & 0x1);
    }

    /**
     * bit 转换为byte
     *
     * @param byteStr 位字符串
     * @return
     */
    public static byte bitToByte(String byteStr) {
        int re, len;
        if (null == byteStr) {
            return 0;
        }
        len = byteStr.length();
        if (len != 4 && len != 8) {
            return 0;
        }
        if (len == 8) {// 8 bit处理
            if (byteStr.charAt(0) == '0') {// 正数
                re = Integer.parseInt(byteStr, 2);
            } else {// 负数
                re = Integer.parseInt(byteStr, 2) - 256;
            }
        } else {//4 bit处理
            re = Integer.parseInt(byteStr, 2);
        }
        return (byte) re;
    }

    public static String getHexString(byte[] bs, int start, int end) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (bs == null || bs.length <= 0) {
            return null;
        }
        for (int i = start; i < end; i++) {
            int v = bs[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }


    //bytes to string
    public static String getHexString(byte[] bs) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (bs == null || bs.length <= 0) {
            return null;
        }
        for (int i = 0; i < bs.length; i++) {
            int v = bs[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    //Hex String to bytes
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || "".equals(hexString)) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static String getString(byte[] bytes) {
        return getString(bytes, "GBK");
    }

    public static String getUTFString(byte[] bytes) {
        return new String(bytes);
    }

    public static String getString(byte[] bytes, String charsetName) {
        return new String(bytes, Charset.forName(charsetName));
    }

    /**
     * Ascii转换为字符串
     *
     * @param value
     * @return
     */
    public static String asciiToString(String value) {
        StringBuilder sbu = new StringBuilder();
        String[] chars = value.split(",");
        for (int i = 0; i < chars.length; i++) {
            sbu.append((char) Integer.parseInt(chars[i]));
        }
        return sbu.toString();
    }

    /**
     * 浮点转换为字节 (小端模式)
     *
     * @param f
     * @return
     */
    public static byte[] floatTobyteLittle(float f) {

        // 把float转换为byte[]
        int fbit = Float.floatToIntBits(f);

        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            b[i] = (byte) (fbit >> (24 - i * 8));
        }

        // 翻转数组
        int len = b.length;
        // 建立一个与源数组元素类型相同的数组
        byte[] dest = new byte[len];
        // 为了防止修改源数组，将源数组拷贝一份副本
        System.arraycopy(b, 0, dest, 0, len);
        byte temp;
        // 将顺位第i个与倒数第i个交换
        for (int i = 0; i < len / 2; ++i) {
            temp = dest[i];
            dest[i] = dest[len - i - 1];
            dest[len - i - 1] = temp;
        }

        return dest;

    }

}
