package com.njzscloud.common.localizer.jt808.support;

import com.njzscloud.common.localizer.jt808.JT808;
import com.njzscloud.common.localizer.jt808.message.JT808Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * JT808协议解码器
 * 用于解析JT808协议格式的字节流为消息对象
 */
@Slf4j
public class JT808Decoder extends ByteToMessageDecoder {
    // 消息起始符和结束符
    private static final byte MSG_DELIMITER = 0x7e;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        // 确保至少有2个字节（起始符+至少一个字节）
        if (in.readableBytes() < 2) {
            return;
        }

        // 寻找消息起始符
        int startIndex = -1;
        while (in.readableBytes() > 0) {
            if (in.readByte() == MSG_DELIMITER) {
                startIndex = in.readerIndex() - 1;
                break;
            }
        }

        if (startIndex == -1) {
            // 未找到起始符，清空缓冲区
            in.clear();
            return;
        }

        // 寻找消息结束符
        int endIndex = -1;
        for (int i = in.readerIndex(); i < in.writerIndex(); i++) {
            if (in.getByte(i) == MSG_DELIMITER) {
                endIndex = i;
                break;
            }
        }

        if (endIndex == -1) {
            // 未找到结束符，等待更多数据
            in.readerIndex(startIndex);
            return;
        }

        // 读取完整消息（不包含起始符和结束符）
        int messageLength = endIndex - startIndex - 1;
        ByteBuf messageBuf = in.slice(startIndex + 1, messageLength);

        // 处理转义字符
        ByteBuf unescapedBuf = handleEscape(messageBuf);

        // 解析消息内容
        JT808Message message = JT808.parseMessage(unescapedBuf);
        unescapedBuf.release();
        if (message != null) {
            out.add(message);
        }

        // 移动读指针到结束符之后
        in.readerIndex(endIndex + 1);
    }

    /**
     * 处理转义字符
     * JT808协议规定：0x7e <-> 0x7d 0x01，0x7d <-> 0x7d 0x02
     */
    private ByteBuf handleEscape(ByteBuf buf) {
        ByteBuf out = buf.alloc().buffer(buf.readableBytes());

        while (buf.readableBytes() > 0) {
            byte b = buf.readByte();
            if (b == 0x7d) {
                if (buf.readableBytes() > 0) {
                    byte next = buf.readByte();
                    if (next == 0x01) {
                        out.writeByte(0x7e);
                    } else if (next == 0x02) {
                        out.writeByte(0x7d);
                    } else {
                        // 无效的转义序列，直接写入
                        out.writeByte(b);
                        out.writeByte(next);
                    }
                } else {
                    out.writeByte(b);
                }
            } else {
                out.writeByte(b);
            }
        }

        out.resetReaderIndex();
        return out;
    }
}
