/* P0 测试：remoteDisplay 协议核心
 * 目标：
 * - 校验 CRC 纯函数行为（calc_crc）
 * - 校验 Protocol_ByteHandler 状态机解析行为
 */
#include <stdint.h>
#include <string.h>

#include "test_common.h"
#include "../src/remoteDisplayProtocol.h"

/* 用例1：CRC 计算
 * - 空数据长度应返回 0
 * - 常规 payload 应返回逐字节异或结果
 */
static int test_calc_crc(void)
{
    const uint8_t payload[] = {0x12, 0x34, 0x56};
    ASSERT_EQ_INT(0x00, calc_crc(NULL, 0));
    ASSERT_EQ_INT((0x12 ^ 0x34 ^ 0x56), calc_crc(payload, 3));
    return 0;
}

/* 用例2：Protocol_ByteHandler 基本帧解析
 * 验证：完整 RemoDispBus 帧按字节输入后，状态机完成帧解析并保持正确 cmd/data
 */
static int test_protocol_byte_handler_ok(void)
{
    protocol_instance_t proto_ins;
    const uint8_t payload[] = {0x10, 0x20};
    const uint8_t frame[] = {
        TAG_CLIENT,
        CMD_KEY,
        0x00,
        (uint8_t)sizeof(payload),
        payload[0],
        payload[1],
        (uint8_t)(payload[0] ^ payload[1])
    };

    protocol_init(&proto_ins);
    ASSERT_EQ_INT(PROTO_STATE_WAIT_TAG, proto_ins.state);
    ASSERT_EQ_INT(0, proto_ins.frame_done_flag);

    for (unsigned int i = 0; i < sizeof(frame); ++i) {
        protocol_byte_handler(&proto_ins, frame[i]);
    }

    ASSERT_EQ_INT(1, proto_ins.frame_done_flag);
    ASSERT_EQ_INT(CMD_KEY, proto_ins.recv_cmd);
    ASSERT_EQ_INT((int)sizeof(payload), (int)proto_ins.expect_data_len);
    ASSERT_EQ_INT((int)sizeof(payload), (int)proto_ins.recv_len);
    ASSERT_EQ_INT(payload[0], proto_ins.recv_buf[0]);
    ASSERT_EQ_INT(payload[1], proto_ins.recv_buf[1]);
    return 0;
}

/* 用例3：Protocol_ByteHandler CRC 错误处理
 * 验证：CRC 校验失败后状态机重置为 WAIT_TAG，不置完成标志
 */
static int test_protocol_byte_handler_bad_crc(void)
{
    protocol_instance_t proto_ins;
    const uint8_t payload[] = {0x10, 0x20};
    const uint8_t frame[] = {
        TAG_CLIENT,
        CMD_KEY,
        0x00,
        (uint8_t)sizeof(payload),
        payload[0],
        payload[1],
        0xFF
    };

    protocol_init(&proto_ins);
    for (unsigned int i = 0; i < sizeof(frame); ++i) {
        protocol_byte_handler(&proto_ins, frame[i]);
    }

    ASSERT_EQ_INT(PROTO_STATE_WAIT_TAG, proto_ins.state);
    ASSERT_EQ_INT(0, proto_ins.frame_done_flag);
    return 0;
}

/* 测试入口：按顺序执行各子用例，任一失败即返回非 0 */
int main(void)
{
    if (test_calc_crc() != 0) return 1;
    if (test_protocol_byte_handler_ok() != 0) return 1;
    if (test_protocol_byte_handler_bad_crc() != 0) return 1;
    return 0;
}
