#include "../src/lamp_tx_queue.h"

#include <assert.h>
#include <stdint.h>
#include <stdio.h>

static void test_packet_atomicity(void)
{
    lamp_tx_queue queue;
    const uint8_t packet[] = {0x4Eu, 0x4Cu, 0x41u, 0x49u, 0x02u, 0x30u};
    uint8_t byte = 0u;

    lamp_tx_queue_init(&queue);
    assert(lamp_tx_queue_count(&queue) == 0u);
    assert(!lamp_tx_queue_pop(&queue, &byte));
    assert(lamp_tx_queue_push(&queue, packet, sizeof(packet)));
    assert(lamp_tx_queue_count(&queue) == sizeof(packet));
    assert(!lamp_tx_queue_push(&queue, NULL, 1u));
    assert(!lamp_tx_queue_push(&queue, packet, 0u));
    for (size_t i = 0u; i < sizeof(packet); ++i) {
        assert(lamp_tx_queue_pop(&queue, &byte));
        assert(byte == packet[i]);
    }
    assert(!lamp_tx_queue_pop(&queue, &byte));
}

static void test_full_queue_and_wraparound(void)
{
    lamp_tx_queue queue;
    uint8_t source[LAMP_TX_QUEUE_USABLE];
    uint8_t byte = 0u;

    lamp_tx_queue_init(&queue);
    for (size_t i = 0u; i < sizeof(source); ++i) {
        source[i] = (uint8_t)i;
    }
    assert(lamp_tx_queue_push(&queue, source, sizeof(source)));
    assert(lamp_tx_queue_count(&queue) == LAMP_TX_QUEUE_USABLE);
    assert(!lamp_tx_queue_push(&queue, source, 1u));
    assert(lamp_tx_queue_count(&queue) == LAMP_TX_QUEUE_USABLE);
    for (size_t i = 0u; i < 31u; ++i) {
        assert(lamp_tx_queue_pop(&queue, &byte));
        assert(byte == (uint8_t)i);
    }
    for (size_t i = 0u; i < 31u; ++i) source[i] = (uint8_t)(100u + i);
    assert(lamp_tx_queue_push(&queue, source, 31u));
    assert(lamp_tx_queue_count(&queue) == LAMP_TX_QUEUE_USABLE);
    for (size_t i = 31u; i < LAMP_TX_QUEUE_USABLE; ++i) {
        assert(lamp_tx_queue_pop(&queue, &byte));
        assert(byte == (uint8_t)i);
    }
    for (size_t i = 0u; i < 31u; ++i) {
        assert(lamp_tx_queue_pop(&queue, &byte));
        assert(byte == (uint8_t)(100u + i));
    }
    assert(lamp_tx_queue_count(&queue) == 0u);
}

int main(void)
{
    test_packet_atomicity();
    test_full_queue_and_wraparound();
    puts("PASS: UART TX queue preserves whole packets, rejects overflow atomically and wraps safely.");
    return 0;
}
