/* 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 <osmocom/gapk/procqueue.h>

/* crate a new (empty) processing queue */
struct osmo_gapk_pq *
osmo_gapk_pq_create(void)
{
	return (struct osmo_gapk_pq *) calloc(1, sizeof(struct osmo_gapk_pq));
}

/*! destroy a processing queue, calls exit() callback of each item
 *  \param[in] pq Processing Queue to be destroyed */
void
osmo_gapk_pq_destroy(struct osmo_gapk_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]->buf);
		free(pq->items[i]);
	}

	free(pq);
}

/*! allocate + add an item to a processing queue; return new item
 *  \param[in] pq Processing Queue to which item is added
 *  \returns new PQ item; NULL on error */
struct osmo_gapk_pq_item *
osmo_gapk_pq_add_item(struct osmo_gapk_pq *pq)
{
	struct osmo_gapk_pq_item *item;

	if (pq->n_items == MAX_PQ_ITEMS) {
		fprintf(stderr, "[!] Processing Queue cannot handle more than %u items\n",
			MAX_PQ_ITEMS);
		return NULL;
	}

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

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

	return item;
}

/*! prepare a processing queue; allocates buffers; checks lengths
 *  \param[in] pq Processing Queue to be prepared
 *  \returns 0 on succcess; negative on error */
int
osmo_gapk_pq_prepare(struct osmo_gapk_pq *pq)
{
	int i;
	unsigned int len_prev;

	len_prev = 0;

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

		if (item->len_in && item->len_in != len_prev) {
			fprintf(stderr, "[!] PQ item requires input size %u, but previous output is %u\n",
				item->len_in, len_prev);
			return -EINVAL;
		}

		if (i < (pq->n_items-1)) {
			unsigned int buf_size = item->len_out;
			/* variable-length codec output, use maximum
			 * known buffer size */
			if (!buf_size)
				buf_size = VAR_BUF_SIZE;

			item->buf = malloc(buf_size);
			if (!item->buf)
				return -ENOMEM;
		} else{
			if (item->len_out)
				return -EINVAL;
		}

		len_prev = item->len_out;
	}

	return 0;
}

/*! execute a processing queue; iterate over processing elements
 *  \param[in] pq Processing Queue to be executed
 *  \returns 0 on success; negative on error (if any item returns negative) */
int
osmo_gapk_pq_execute(struct osmo_gapk_pq *pq)
{
	int i;
	void *buf_prev, *buf;
	unsigned int len_prev;

	buf_prev = NULL;
	len_prev = 0;

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

		buf = i < (pq->n_items-1) ? item->buf : NULL;

		rv = item->proc(item->state, buf, buf_prev, len_prev);
		if (rv < 0) {
			fprintf(stderr, "[!] osmo_gapk_pq_execute(): abort, item returned %d\n", rv);
			return rv;
		}

		buf_prev = buf;
		len_prev = rv;
	}

	return 0;
}
