#include <transport.h>
#include <transport_private.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

static struct list
{
    union transport_packet p;
    bool used;
} list[16];

static union transport_packet *packets[sizeof list / sizeof *list];

union transport_packet *transport_packet_alloc(const enum transport_packet_type t)
{
    for (size_t i = 0; i < sizeof list / sizeof *list; i++)
    {
        struct list *const l = &list[i];

        if (!l->used)
        {
            union transport_packet *const p = &l->p;

            l->used = true;
            *p = (const union transport_packet)
            {
                .common =
                {
                    .type = t
                }
            };

            return p;
        }
    }

    return NULL;
}

int transport_append(struct transport_handle *const h,
    union transport_packet *const p)
{
    if (h->n_packets >= sizeof packets / sizeof *packets)
        return -1;

    packets[h->n_packets++] = p;
    h->packets = packets;
    return 0;
}

void transport_packet_free(union transport_packet *const p)
{
    for (size_t i = 0; i < sizeof list / sizeof *list; i++)
    {
        struct list *const l = &list[i];

        if (p == &l->p)
        {
            l->used = false;
            return;
        }
    }
}

int transport_pop(struct transport_handle *const h)
{
    transport_packet_free(h->packets[h->n_packets - 1]);
    return 0;
}
