#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

char *tp_filter__asprintf_inout_int_list(const char *field, bool in, size_t nints, int *ints)
{
	/*
 	 * FIXME: replace this with an expression using log10() when we
 	 * find a suitable implementation, maybe the one in the dvb drivers...
 	 *
 	 * "%s == %d || " = log10(MAXINT) * 2 + 8 chars for the operators
 	 */
	size_t size = nints * 28 + 1; /* \0 */
	int ret = -1;
	size_t i, printed = 0;
	char *filter = malloc(size);;

	if (filter) {
		const char *or_and = "||", *eq_neq = "==";
		char *f = filter;

		if (!in) {
			or_and = "&&";
			eq_neq = "!=";
		}

		for (i = 0; i < nints; ++i) {
			if (i > 0)
				printed += snprintf(f + printed, size - printed, " %s ", or_and);
			printed += snprintf(f + printed, size - printed, "%s %s %d", field, eq_neq, ints[i]);
		}
	}

	return filter;
}

static inline char *tp_filter__asprintf_in_int_list(const char *field, size_t nints, int *ints)
{
	return tp_filter__asprintf_inout_int_list(field, true, nints, ints);
}

static inline char *tp_filter__asprintf_not_in_int_list(const char *field, size_t nints, int *ints)
{
	return tp_filter__asprintf_inout_int_list(field, false, nints, ints);
}

static char *tp_filter__asprintf_in_sint_list(int argc, char *argv[])
{
	char *filter = NULL;
	int *ints = malloc(argc * sizeof(*ints));

	if (ints) {
		int i;
		for (i = 0; i < argc; ++i)
			ints[i] = atoi(argv[i]);

		filter = tp_filter__asprintf_in_int_list("id", argc, ints);
		free(ints);
	}

	return filter;
}

static char *tp_filter__asprintf_not_in_sint_list(int argc, char *argv[])
{
	char *filter = NULL;
	int *ints = malloc(argc * sizeof(*ints));

	if (ints) {
		int i;
		for (i = 0; i < argc; ++i)
			ints[i] = atoi(argv[i]);

		filter = tp_filter__asprintf_not_in_int_list("id", argc, ints);
		free(ints);
	}

	return filter;
}

int main(int argc, char *argv[])
{
	char *in = tp_filter__asprintf_in_sint_list(argc, argv),
	     *not_in = tp_filter__asprintf_not_in_sint_list(argc, argv);

	return printf("in:  %s\n!in: %s\n", in, not_in);
}
