package com.lingniu.ingest.protocol.jt808.codec;

/**
 * JT/T 808 转义规则：
 * <pre>
 *   0x7e → 0x7d 0x02
 *   0x7d → 0x7d 0x01
 * </pre>
 * 转义仅作用于 <b>消息头 + 消息体 + 校验码</b>，不包含首尾的 0x7e 标识位。
 */
public final class Jt808Escape {

    private Jt808Escape() {}

    /** 反转义：从 framed 字节数组中剥除 0x7e 首尾后，恢复原始字节。 */
    public static byte[] unescape(byte[] framed, int offset, int length) {
        byte[] out = new byte[length];
        int outLen = 0;
        for (int i = offset; i < offset + length; i++) {
            byte b = framed[i];
            if (b == 0x7d && i + 1 < offset + length) {
                byte next = framed[i + 1];
                if (next == 0x02) {
                    out[outLen++] = 0x7e;
                    i++;
                    continue;
                } else if (next == 0x01) {
                    out[outLen++] = 0x7d;
                    i++;
                    continue;
                }
            }
            out[outLen++] = b;
        }
        byte[] trimmed = new byte[outLen];
        System.arraycopy(out, 0, trimmed, 0, outLen);
        return trimmed;
    }

    /** 转义：在原始字节上应用 7d/7e 替换，结果不含首尾 0x7e。 */
    public static byte[] escape(byte[] raw) {
        byte[] out = new byte[raw.length * 2];
        int outLen = 0;
        for (byte b : raw) {
            if (b == 0x7e) {
                out[outLen++] = 0x7d;
                out[outLen++] = 0x02;
            } else if (b == 0x7d) {
                out[outLen++] = 0x7d;
                out[outLen++] = 0x01;
            } else {
                out[outLen++] = b;
            }
        }
        byte[] trimmed = new byte[outLen];
        System.arraycopy(out, 0, trimmed, 0, outLen);
        return trimmed;
    }
}
