/* Processing Queue Management */

/*
 * This file is part of gapk (GSM Audio Pocket Knife).
 *
 * gapk is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * gapk is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gapk.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>

#include <gapk/procqueue.h>


#define MAX_PQ_ITEMS	8

struct pq {
	int		n_items;
	struct pq_item* items[MAX_PQ_ITEMS];
	void *		buffers[MAX_PQ_ITEMS+1];
};


struct pq *
pq_create(void)
{
	return (struct pq *) calloc(1, sizeof(struct pq));
}

void
pq_destroy(struct pq *pq)
{
	int i;

	if (!pq)
		return;

	for (i=0; i<pq->n_items; i++) {
		if (!pq->items[i])
			continue;
		if (pq->items[i]->exit)
			pq->items[i]->exit(pq->items[i]->state);
		free(pq->items[i]);
	}

	for (i=0; i<pq->n_items-1; i++)
		free(pq->buffers[i]); /* free is NULL safe */

	free(pq);
}

struct pq_item *
pq_add_item(struct pq *pq)
{
	struct pq_item *item;

	if (pq->n_items == MAX_PQ_ITEMS)
		return NULL;

	item = calloc(1, sizeof(struct pq_item));
	if (!item)
		return NULL;

	pq->items[pq->n_items++] = item;

	return item;
}

int
pq_prepare(struct pq *pq)
{
	int i;
	unsigned int len_prev;

	len_prev = 0;

	for (i=0; i<pq->n_items; i++) {
		struct pq_item *item = pq->items[i];

		if (item->len_in != len_prev)
			return -EINVAL;

		if (i < (pq->n_items-1)) {
			pq->buffers[i] = malloc(item->len_out);
			if (!pq->buffers[i])
				return -ENOMEM;
		} else{
			if (item->len_out)
				return -EINVAL;
		}

		len_prev = item->len_out;
	}

	return 0;
}

int
pq_execute(struct pq *pq)
{
	int i;
	void *buf_prev, *buf;

	buf_prev = NULL;

	for (i=0; i<pq->n_items; i++) {
		int rv;
		struct pq_item *item = pq->items[i];

		buf = i < (pq->n_items-1) ? pq->buffers[i] : NULL;

		rv = item->proc(item->state, buf, buf_prev);
		if (rv)
			return rv;

		buf_prev = buf;
	}

	return 0;
}
