package com.example.m20_gamepad.network

import com.example.m20_gamepad.network.models.ApduMessage
import com.example.m20_gamepad.network.models.Header

/**
 * 报文解码器。将接收到的字节数组解析为 ApduMessage。
 */
object PacketDecoder {

    /**
     * 从字节数组解码完整 APDU 报文。
     * 如果数据不足或同步头校验失败，返回 null。
     */
    fun decode(data: ByteArray): ApduMessage? {
        if (data.size < Header.SIZE) return null

        val header = Header.fromBytes(data) ?: return null
        if (header.format != Header.FORMAT_JSON.toInt()) return null

        // 检查数据长度是否足够包含 ASDU
        val totalSize = Header.SIZE + header.length
        if (data.size < totalSize) return null

        val asduBytes = data.copyOfRange(Header.SIZE, totalSize)
        val asdu = asduBytes.toString(Charsets.UTF_8)

        return ApduMessage(header = header, asdu = asdu)
    }

    /**
     * 从字节数组中查找第一个完整且合法的 APDU 报文。
     * 用于在可能包含多个报文或部分数据的缓冲区中搜索。
     *
     * @return 解析结果 + 消耗的字节数；如果未找到返回 null
     */
    fun findFirst(data: ByteArray): Pair<ApduMessage, Int>? {
        var offset = 0
        while (offset <= data.size - Header.SIZE) {
            // 查找同步头起始位置
            if (data[offset] != Header.SYNC0 ||
                data[offset + 1] != Header.SYNC1 ||
                data[offset + 2] != Header.SYNC2 ||
                data[offset + 3] != Header.SYNC3
            ) {
                offset++
                continue
            }

            // 尝试从该位置解码
            val remaining = data.copyOfRange(offset, data.size)
            val message = decode(remaining) ?: run {
                offset++
                continue
            }

            val consumed = Header.SIZE + message.header.length
            return message to consumed
        }
        return null
    }
}