package com.unibuy.smartdevice.devices;

import java.util.List;

public class PortTools {
    public static byte[] catByteArrays(byte[] array1, int index) {
        return catByteArrays(array1, index, array1.length-index);
    }

    public static byte[] catByteArrays(byte[] array1, int index, int count) {
        byte[] result = new byte[count];

        System.arraycopy(array1, index, result, 0, count);

        return result;
    }

    public static byte[] concatByteArrays(byte byte1, byte byte2) {
        return concatByteArrays(new byte[]{byte1}, new byte[]{byte2});
    }

    public static byte[] concatByteArrays(byte[] array1, byte[] array2) {
        byte[] result = new byte[array1.length + array2.length];

        // 複製第一個陣列
        System.arraycopy(array1, 0, result, 0, array1.length);

        // 複製第二個陣列
        System.arraycopy(array2, 0, result, array1.length, array2.length);

        return result;
    }

    public static byte[] subtractByteArrays(byte[] array1, int count) {
        byte[] result = new byte[array1.length-count];

        // 複製第一個陣列
        System.arraycopy(array1, 0, result, 0, array1.length-1);

        return result;
    }

    public static byte[] intToByte8(int decimal, int count) {
        byte[] bytes = new byte[count];
        for(int i=0; i<count; i++) {
            bytes[count-1-i] = (byte) (decimal >> 8*i);
        }
        return bytes;
    }

    public static byte[] charToByte8(String string, int count) {
        byte[] buffer = new byte[0];
        for (int index = string.length()-1; index >= 0; index --) {
            char character = string.charAt(index);
            int unicode = Character.codePointAt(new char[]{character}, 0);
            buffer = PortTools.concatByteArrays(buffer, PortTools.intToByte8(unicode, count));
        }
        return buffer;
    }

    public static int byte8ToInt(byte byte0, byte byte1, byte byte2, byte byte3) {
        byte[] bytes = new byte[]{byte0, byte1, byte2, byte3};
        return byte8ToInt(bytes);
    }

    public static int byte8ToInt(byte byte0, byte byte1, byte byte2) {
        byte[] bytes = new byte[]{byte0, byte1, byte2};
        return byte8ToInt(bytes);
    }

    public static int byte8ToInt(byte byte0, byte byte1) {
        byte[] bytes = new byte[]{byte0, byte1};
        return byte8ToInt(bytes);
    }

    public static int byte8ToInt(byte byte0) {
        byte[] bytes = new byte[]{byte0};
        return byte8ToInt(bytes);
    }

    public static int byte8ToInt(byte[] bytes) {
        int result = 0;
        for(int i=0; i<bytes.length; i++) {
            result = (result << 8) | (bytes[i] & 0xFF);
        }
        return result;
    }

    public static byte tenToHexToByte(int decimal) {
        String hexString = Integer.toHexString(decimal).toUpperCase();
        return (byte) Integer.parseInt(hexString, 16);
    }

    public static String showBinary(byte[] data) {
        StringBuilder binaryStringBuilder = new StringBuilder();

        for (int i = 0; i < data.length; i++) {
            // 將 byte 轉成二進位字串並補 0
            String binaryString = String.format("%8s", Integer.toBinaryString(data[i] & 0xFF))
                    .replace(' ', '0');
            binaryStringBuilder.append(binaryString);

            // 在每個二進位字串後加一個空格（除了最後一個）
            if (i < data.length - 1) {
                binaryStringBuilder.append(" ");
            }
        }

        return binaryStringBuilder.toString();
    }

    public static String showHex(byte data) {
        return showHex(new byte[]{data});
    }
    public static String showHex(byte[] data) {
        StringBuilder hexStringBuilder = new StringBuilder();

        for (int i = 0; i < data.length; i++) {
            // 將 byte 轉成十六進位字串
            String hexString = String.format("%02X", data[i] & 0xFF);
            hexStringBuilder.append(hexString);

            // 在每個十六進位字串後加一個空格（除了最後一個）
            if (i < data.length - 1) {
                hexStringBuilder.append(" ");
            }
        }

        return hexStringBuilder.toString();
    }

    private static int matchIndex = 0;

    public static int getMatchIndex() {
        return matchIndex;
    }

    public static boolean match(byte oneByte, byte[] matchBytes) {
        if (matchIndex > matchBytes.length-1) matchIndex = 0;
        if (oneByte == matchBytes[matchIndex]) {
            if (matchIndex == matchBytes.length-1) {
                return true;
            } else {
                matchIndex ++;
                return false;
            }
        } else {
            return false;
        }
    }

    public static byte[] calculateCRC(byte[] data, int byteCount) {
        int crc = (byte) 0xFFFF;

        for (int pos = 0; pos < data.length; pos++) {
            crc ^= data[pos] & 0xFF;

            for (int i = 8; i != 0; i--) {
                if ((crc & 0x0001) != 0) {
                    crc >>= 1;
                    crc ^= 0xA001; // Modbus CRC Polynomial
                } else {
                    crc >>= 1;
                }
            }
        }

        return intToByte8(crc, byteCount);
    }
}
