package com.example.m20_gamepad.network.models

import java.nio.ByteBuffer
import java.nio.ByteOrder

/**
 * 16 字节报文头（小端 LE）
 *
 * | 偏移 | 长度 | 字段     | 值              | 说明                  |
 * | ---: | ---: | ---      | ---             | ---                   |
 * | 0    | 1    | Sync0    | 0xEB            | 固定                  |
 * | 1    | 1    | Sync1    | 0x91            | 固定                  |
 * | 2    | 1    | Sync2    | 0xEB            | 固定                  |
 * | 3    | 1    | Sync3    | 0x90            | 固定                  |
 * | 4    | 2    | Length   | u16 LE          | ASDU 字节长度          |
 * | 6    | 2    | MsgId    | u16 LE          | 请求/响应配对           |
 * | 8    | 1    | Format   | 0x01            | JSON                  |
 * | 9    | 7    | Reserved | 0x00 * 7        | 预留                  |
 */
data class Header(
    val length: Int,       // ASDU 字节长度 (u16)
    val msgId: Int,        // 消息 ID (u16), 0-65535
    val format: Int = 0x01 // 0x01 = JSON
) {
    companion object {
        const val SIZE = 16
        val SYNC0: Byte = 0xEB.toByte()
        val SYNC1: Byte = 0x91.toByte()
        val SYNC2: Byte = 0xEB.toByte()
        val SYNC3: Byte = 0x90.toByte()
        val FORMAT_JSON: Byte = 0x01.toByte()

        /**
         * 从字节数组解码 Header
         */
        fun fromBytes(data: ByteArray): Header? {
            if (data.size < SIZE) return null

            val buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN)

            // 校验同步头
            if (buffer.get() != SYNC0) return null
            if (buffer.get() != SYNC1) return null
            if (buffer.get() != SYNC2) return null
            if (buffer.get() != SYNC3) return null

            val length = buffer.short.toInt() and 0xFFFF
            val msgId = buffer.short.toInt() and 0xFFFF
            val format = buffer.get().toInt() and 0xFF

            return Header(length = length, msgId = msgId, format = format)
        }
    }

    /**
     * 编码 Header 为 16 字节数组（小端 LE）
     */
    fun toBytes(): ByteArray {
        val buffer = ByteBuffer.allocate(SIZE).order(ByteOrder.LITTLE_ENDIAN)
        buffer.put(SYNC0)
        buffer.put(SYNC1)
        buffer.put(SYNC2)
        buffer.put(SYNC3)
        buffer.putShort(length.toShort())
        buffer.putShort(msgId.toShort())
        buffer.put(format.toByte())
        // Reserved 7 字节，默认 0x00
        buffer.put(ByteArray(7))
        return buffer.array()
    }
}