// SPDX-License-Identifier: LGPL-2.1
/*
 * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/types.h>

#include "event-parse.h"
#include "event-parse-local.h"
#include "event-utils.h"

#define COMM "COMM"
#define CPU "CPU"

static struct tep_format_field comm = {
	.name = "COMM",
};

static struct tep_format_field cpu = {
	.name = "CPU",
};

struct event_list {
	struct event_list	*next;
	struct tep_event	*event;
};

static void show_error(char *error_buf, const char *fmt, ...)
{
	unsigned long long index;
	const char *input;
	va_list ap;
	int len;
	int i;

	input = get_input_buf();
	index = get_input_buf_ptr();
	len = input ? strlen(input) : 0;

	if (len) {
		strcpy(error_buf, input);
		error_buf[len] = '\n';
		for (i = 1; i < len && i < index; i++)
			error_buf[len+i] = ' ';
		error_buf[len + i] = '^';
		error_buf[len + i + 1] = '\n';
		len += i+2;
	}

	va_start(ap, fmt);
	vsnprintf(error_buf + len, TEP_FILTER_ERROR_BUFSZ - len, fmt, ap);
	va_end(ap);
}

static enum tep_event_type filter_read_token(char **tok)
{
	enum tep_event_type type;
	char *token = NULL;

	do {
		free_token(token);
		type = read_token(&token);
	} while (type == TEP_EVENT_NEWLINE || type == TEP_EVENT_SPACE);

	/* If token is = or ! check to see if the next char is ~ */
	if (token &&
	    (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
	    peek_char() == '~') {
		/* append it */
		*tok = malloc(3);
		if (*tok == NULL) {
			free_token(token);
			return TEP_EVENT_ERROR;
		}
		sprintf(*tok, "%c%c", *token, '~');
		free_token(token);
		/* Now remove the '~' from the buffer */
		read_token(&token);
		free_token(token);
	} else
		*tok = token;

	return type;
}

static int filter_cmp(const void *a, const void *b)
{
	const struct tep_filter_type *ea = a;
	const struct tep_filter_type *eb = b;

	if (ea->event_id < eb->event_id)
		return -1;

	if (ea->event_id > eb->event_id)
		return 1;

	return 0;
}

static struct tep_filter_type *
find_filter_type(struct tep_event_filter *filter, int id)
{
	struct tep_filter_type *filter_type;
	struct tep_filter_type key;

	key.event_id = id;

	filter_type = bsearch(&key, filter->event_filters,
			      filter->filters,
			      sizeof(*filter->event_filters),
			      filter_cmp);

	return filter_type;
}

static struct tep_filter_type *
add_filter_type(struct tep_event_filter *filter, int id)
{
	struct tep_filter_type *filter_type;
	int i;

	filter_type = find_filter_type(filter, id);
	if (filter_type)
		return filter_type;

	filter_type = realloc(filter->event_filters,
			      sizeof(*filter->event_filters) *
			      (filter->filters + 1));
	if (!filter_type)
		return NULL;

	filter->event_filters = filter_type;

	for (i = 0; i < filter->filters; i++) {
		if (filter->event_filters[i].event_id > id)
			break;
	}

	if (i < filter->filters)
		memmove(&filter->event_filters[i+1],
			&filter->event_filters[i],
			sizeof(*filter->event_filters) *
			(filter->filters - i));

	filter_type = &filter->event_filters[i];
	filter_type->event_id = id;
	filter_type->event = tep_find_event(filter->tep, id);
	filter_type->filter = NULL;

	filter->filters++;

	return filter_type;
}

/**
 * tep_filter_alloc - create a new event filter
 * @tep: The tep that this filter is associated with
 */
struct tep_event_filter *tep_filter_alloc(struct tep_handle *tep)
{
	struct tep_event_filter *filter;

	filter = malloc(sizeof(*filter));
	if (filter == NULL)
		return NULL;

	memset(filter, 0, sizeof(*filter));
	filter->tep = tep;
	tep_ref(tep);

	return filter;
}

static struct tep_filter_arg *allocate_arg(void)
{
	return calloc(1, sizeof(struct tep_filter_arg));
}

static void free_arg(struct tep_filter_arg *arg)
{
	if (!arg)
		return;

	switch (arg->type) {
	case TEP_FILTER_ARG_NONE:
	case TEP_FILTER_ARG_BOOLEAN:
		break;

	case TEP_FILTER_ARG_NUM:
		free_arg(arg->num.left);
		free_arg(arg->num.right);
		break;

	case TEP_FILTER_ARG_EXP:
		free_arg(arg->exp.left);
		free_arg(arg->exp.right);
		break;

	case TEP_FILTER_ARG_STR:
		free(arg->str.val);
		regfree(&arg->str.reg);
		free(arg->str.buffer);
		break;

	case TEP_FILTER_ARG_VALUE:
		if (arg->value.type == TEP_FILTER_STRING ||
		    arg->value.type == TEP_FILTER_CHAR)
			free(arg->value.str);
		break;

	case TEP_FILTER_ARG_OP:
		free_arg(arg->op.left);
		free_arg(arg->op.right);
	default:
		break;
	}

	free(arg);
}

static int add_event(struct event_list **events,
		     struct tep_event *event)
{
	struct event_list *list;

	list = malloc(sizeof(*list));
	if (list == NULL)
		return -1;

	list->next = *events;
	*events = list;
	list->event = event;
	return 0;
}

static int event_match(struct tep_event *event,
		       regex_t *sreg, regex_t *ereg)
{
	if (sreg) {
		return !regexec(sreg, event->system, 0, NULL, 0) &&
			!regexec(ereg, event->name, 0, NULL, 0);
	}

	return !regexec(ereg, event->system, 0, NULL, 0) ||
		!regexec(ereg, event->name, 0, NULL, 0);
}

static enum tep_errno
find_event(struct tep_handle *tep, struct event_list **events,
	   char *sys_name, char *event_name)
{
	struct tep_event *event;
	regex_t ereg;
	regex_t sreg;
	int match = 0;
	int fail = 0;
	char *reg;
	int ret;
	int i;

	if (!event_name) {
		/* if no name is given, then swap sys and name */
		event_name = sys_name;
		sys_name = NULL;
	}

	ret = asprintf(&reg, "^%s$", event_name);
	if (ret < 0)
		return TEP_ERRNO__MEM_ALLOC_FAILED;

	ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
	free(reg);

	if (ret)
		return TEP_ERRNO__INVALID_EVENT_NAME;

	if (sys_name) {
		ret = asprintf(&reg, "^%s$", sys_name);
		if (ret < 0) {
			regfree(&ereg);
			return TEP_ERRNO__MEM_ALLOC_FAILED;
		}

		ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
		free(reg);
		if (ret) {
			regfree(&ereg);
			return TEP_ERRNO__INVALID_EVENT_NAME;
		}
	}

	for (i = 0; i < tep->nr_events; i++) {
		event = tep->events[i];
		if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
			match = 1;
			if (add_event(events, event) < 0) {
				fail = 1;
				break;
			}
		}
	}

	regfree(&ereg);
	if (sys_name)
		regfree(&sreg);

	if (!match)
		return TEP_ERRNO__EVENT_NOT_FOUND;
	if (fail)
		return TEP_ERRNO__MEM_ALLOC_FAILED;

	return 0;
}

static void free_events(struct event_list *events)
{
	struct event_list *event;

	while (events) {
		event = events;
		events = events->next;
		free(event);
	}
}

static enum tep_errno
create_arg_item(struct tep_event *event, const char *token,
		enum tep_event_type type, struct tep_filter_arg **parg, char *error_str)
{
	struct tep_format_field *field;
	struct tep_filter_arg *arg;

	arg = allocate_arg();
	if (arg == NULL) {
		show_error(error_str, "failed to allocate filter arg");
		return TEP_ERRNO__MEM_ALLOC_FAILED;
	}

	switch (type) {

	case TEP_EVENT_SQUOTE:
	case TEP_EVENT_DQUOTE:
		arg->type = TEP_FILTER_ARG_VALUE;
		arg->value.type =
			type == TEP_EVENT_DQUOTE ? TEP_FILTER_STRING : TEP_FILTER_CHAR;
		arg->value.str = strdup(token);
		if (!arg->value.str) {
			free_arg(arg);
			show_error(error_str, "failed to allocate string filter arg");
			return TEP_ERRNO__MEM_ALLOC_FAILED;
		}
		break;
	case TEP_EVENT_ITEM:
		/* if it is a number, then convert it */
		if (isdigit(token[0])) {
			arg->type = TEP_FILTER_ARG_VALUE;
			arg->value.type = TEP_FILTER_NUMBER;
			arg->value.val = strtoull(token, NULL, 0);
			break;
		}
		/* Consider this a field */
		field = tep_find_any_field(event, token);
		if (!field) {
			/* If token is 'COMM' or 'CPU' then it is special */
			if (strcmp(token, COMM) == 0) {
				field = &comm;
			} else if (strcmp(token, CPU) == 0) {
				field = &cpu;
			} else {
				/* not a field, Make it false */
				arg->type = TEP_FILTER_ARG_BOOLEAN;
				arg->boolean.value = TEP_FILTER_FALSE;
				break;
			}
		}
		arg->type = TEP_FILTER_ARG_FIELD;
		arg->field.field = field;
		break;
	default:
		free_arg(arg);
		show_error(error_str, "expected a value but found %s", token);
		return TEP_ERRNO__UNEXPECTED_TYPE;
	}
	*parg = arg;
	return 0;
}

static struct tep_filter_arg *
create_arg_op(enum tep_filter_op_type btype)
{
	struct tep_filter_arg *arg;

	arg = allocate_arg();
	if (!arg)
		return NULL;

	arg->type = TEP_FILTER_ARG_OP;
	arg->op.type = btype;

	return arg;
}

static struct tep_filter_arg *
create_arg_exp(enum tep_filter_exp_type etype)
{
	struct tep_filter_arg *arg;

	arg = allocate_arg();
	if (!arg)
		return NULL;

	arg->type = TEP_FILTER_ARG_EXP;
	arg->exp.type = etype;

	return arg;
}

static struct tep_filter_arg *
create_arg_cmp(enum tep_filter_cmp_type ctype)
{
	struct tep_filter_arg *arg;

	arg = allocate_arg();
	if (!arg)
		return NULL;

	/* Use NUM and change if necessary */
	arg->type = TEP_FILTER_ARG_NUM;
	arg->num.type = ctype;

	return arg;
}

static enum tep_errno
add_right(struct tep_filter_arg *op, struct tep_filter_arg *arg, char *error_str)
{
	struct tep_filter_arg *left;
	char *str;
	int op_type;
	int ret;

	switch (op->type) {
	case TEP_FILTER_ARG_EXP:
		if (op->exp.right)
			goto out_fail;
		op->exp.right = arg;
		break;

	case TEP_FILTER_ARG_OP:
		if (op->op.right)
			goto out_fail;
		op->op.right = arg;
		break;

	case TEP_FILTER_ARG_NUM:
		if (op->op.right)
			goto out_fail;
		/*
		 * The arg must be num, str, or field
		 */
		switch (arg->type) {
		case TEP_FILTER_ARG_VALUE:
		case TEP_FILTER_ARG_FIELD:
			break;
		default:
			show_error(error_str, "Illegal rvalue");
			return TEP_ERRNO__ILLEGAL_RVALUE;
		}

		/*
		 * Depending on the type, we may need to
		 * convert this to a string or regex.
		 */
		switch (arg->value.type) {
		case TEP_FILTER_CHAR:
			/*
			 * A char should be converted to number if
			 * the string is 1 byte, and the compare
			 * is not a REGEX.
			 */
			if (strlen(arg->value.str) == 1 &&
			    op->num.type != TEP_FILTER_CMP_REGEX &&
			    op->num.type != TEP_FILTER_CMP_NOT_REGEX) {
				arg->value.type = TEP_FILTER_NUMBER;
				goto do_int;
			}
			/* fall through */
		case TEP_FILTER_STRING:

			/* convert op to a string arg */
			op_type = op->num.type;
			left = op->num.left;
			str = arg->value.str;

			/* reset the op for the new field */
			memset(op, 0, sizeof(*op));

			/*
			 * If left arg was a field not found then
			 * NULL the entire op.
			 */
			if (left->type == TEP_FILTER_ARG_BOOLEAN) {
				free_arg(left);
				free_arg(arg);
				op->type = TEP_FILTER_ARG_BOOLEAN;
				op->boolean.value = TEP_FILTER_FALSE;
				break;
			}

			/* Left arg must be a field */
			if (left->type != TEP_FILTER_ARG_FIELD) {
				show_error(error_str,
					   "Illegal lvalue for string comparison");
				return TEP_ERRNO__ILLEGAL_LVALUE;
			}

			/* Make sure this is a valid string compare */
			switch (op_type) {
			case TEP_FILTER_CMP_EQ:
				op_type = TEP_FILTER_CMP_MATCH;
				break;
			case TEP_FILTER_CMP_NE:
				op_type = TEP_FILTER_CMP_NOT_MATCH;
				break;

			case TEP_FILTER_CMP_REGEX:
			case TEP_FILTER_CMP_NOT_REGEX:
				ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB);
				if (ret) {
					show_error(error_str,
						   "RegEx '%s' did not compute",
						   str);
					return TEP_ERRNO__INVALID_REGEX;
				}
				break;
			default:
				show_error(error_str,
					   "Illegal comparison for string");
				return TEP_ERRNO__ILLEGAL_STRING_CMP;
			}

			op->type = TEP_FILTER_ARG_STR;
			op->str.type = op_type;
			op->str.field = left->field.field;
			op->str.val = strdup(str);
			if (!op->str.val) {
				show_error(error_str, "Failed to allocate string filter");
				return TEP_ERRNO__MEM_ALLOC_FAILED;
			}
			/*
			 * Need a buffer to copy data for tests
			 */
			op->str.buffer = malloc(op->str.field->size + 1);
			if (!op->str.buffer) {
				show_error(error_str, "Failed to allocate string filter");
				return TEP_ERRNO__MEM_ALLOC_FAILED;
			}
			/* Null terminate this buffer */
			op->str.buffer[op->str.field->size] = 0;

			/* We no longer have left or right args */
			free_arg(arg);
			free_arg(left);

			break;

		case TEP_FILTER_NUMBER:

 do_int:
			switch (op->num.type) {
			case TEP_FILTER_CMP_REGEX:
			case TEP_FILTER_CMP_NOT_REGEX:
				show_error(error_str,
					   "Op not allowed with integers");
				return TEP_ERRNO__ILLEGAL_INTEGER_CMP;

			default:
				break;
			}

			/* numeric compare */
			op->num.right = arg;
			break;
		default:
			goto out_fail;
		}
		break;
	default:
		goto out_fail;
	}

	return 0;

 out_fail:
	show_error(error_str, "Syntax error");
	return TEP_ERRNO__SYNTAX_ERROR;
}

static struct tep_filter_arg *
rotate_op_right(struct tep_filter_arg *a, struct tep_filter_arg *b)
{
	struct tep_filter_arg *arg;

	arg = a->op.right;
	a->op.right = b;
	return arg;
}

static enum tep_errno add_left(struct tep_filter_arg *op, struct tep_filter_arg *arg)
{
	switch (op->type) {
	case TEP_FILTER_ARG_EXP:
		if (arg->type == TEP_FILTER_ARG_OP)
			arg = rotate_op_right(arg, op);
		op->exp.left = arg;
		break;

	case TEP_FILTER_ARG_OP:
		op->op.left = arg;
		break;
	case TEP_FILTER_ARG_NUM:
		if (arg->type == TEP_FILTER_ARG_OP)
			arg = rotate_op_right(arg, op);

		/* left arg of compares must be a field */
		if (arg->type != TEP_FILTER_ARG_FIELD &&
		    arg->type != TEP_FILTER_ARG_BOOLEAN)
			return TEP_ERRNO__INVALID_ARG_TYPE;
		op->num.left = arg;
		break;
	default:
		return TEP_ERRNO__INVALID_ARG_TYPE;
	}
	return 0;
}

enum op_type {
	OP_NONE,
	OP_BOOL,
	OP_NOT,
	OP_EXP,
	OP_CMP,
};

static enum op_type process_op(const char *token,
			       enum tep_filter_op_type *btype,
			       enum tep_filter_cmp_type *ctype,
			       enum tep_filter_exp_type *etype)
{
	*btype = TEP_FILTER_OP_NOT;
	*etype = TEP_FILTER_EXP_NONE;
	*ctype = TEP_FILTER_CMP_NONE;

	if (strcmp(token, "&&") == 0)
		*btype = TEP_FILTER_OP_AND;
	else if (strcmp(token, "||") == 0)
		*btype = TEP_FILTER_OP_OR;
	else if (strcmp(token, "!") == 0)
		return OP_NOT;

	if (*btype != TEP_FILTER_OP_NOT)
		return OP_BOOL;

	/* Check for value expressions */
	if (strcmp(token, "+") == 0) {
		*etype = TEP_FILTER_EXP_ADD;
	} else if (strcmp(token, "-") == 0) {
		*etype = TEP_FILTER_EXP_SUB;
	} else if (strcmp(token, "*") == 0) {
		*etype = TEP_FILTER_EXP_MUL;
	} else if (strcmp(token, "/") == 0) {
		*etype = TEP_FILTER_EXP_DIV;
	} else if (strcmp(token, "%") == 0) {
		*etype = TEP_FILTER_EXP_MOD;
	} else if (strcmp(token, ">>") == 0) {
		*etype = TEP_FILTER_EXP_RSHIFT;
	} else if (strcmp(token, "<<") == 0) {
		*etype = TEP_FILTER_EXP_LSHIFT;
	} else if (strcmp(token, "&") == 0) {
		*etype = TEP_FILTER_EXP_AND;
	} else if (strcmp(token, "|") == 0) {
		*etype = TEP_FILTER_EXP_OR;
	} else if (strcmp(token, "^") == 0) {
		*etype = TEP_FILTER_EXP_XOR;
	} else if (strcmp(token, "~") == 0)
		*etype = TEP_FILTER_EXP_NOT;

	if (*etype != TEP_FILTER_EXP_NONE)
		return OP_EXP;

	/* Check for compares */
	if (strcmp(token, "==") == 0)
		*ctype = TEP_FILTER_CMP_EQ;
	else if (strcmp(token, "!=") == 0)
		*ctype = TEP_FILTER_CMP_NE;
	else if (strcmp(token, "<") == 0)
		*ctype = TEP_FILTER_CMP_LT;
	else if (strcmp(token, ">") == 0)
		*ctype = TEP_FILTER_CMP_GT;
	else if (strcmp(token, "<=") == 0)
		*ctype = TEP_FILTER_CMP_LE;
	else if (strcmp(token, ">=") == 0)
		*ctype = TEP_FILTER_CMP_GE;
	else if (strcmp(token, "=~") == 0)
		*ctype = TEP_FILTER_CMP_REGEX;
	else if (strcmp(token, "!~") == 0)
		*ctype = TEP_FILTER_CMP_NOT_REGEX;
	else
		return OP_NONE;

	return OP_CMP;
}

static int check_op_done(struct tep_filter_arg *arg)
{
	switch (arg->type) {
	case TEP_FILTER_ARG_EXP:
		return arg->exp.right != NULL;

	case TEP_FILTER_ARG_OP:
		return arg->op.right != NULL;

	case TEP_FILTER_ARG_NUM:
		return arg->num.right != NULL;

	case TEP_FILTER_ARG_STR:
		/* A string conversion is always done */
		return 1;

	case TEP_FILTER_ARG_BOOLEAN:
		/* field not found, is ok */
		return 1;

	default:
		return 0;
	}
}

enum filter_vals {
	FILTER_VAL_NORM,
	FILTER_VAL_FALSE,
	FILTER_VAL_TRUE,
};

static enum tep_errno
reparent_op_arg(struct tep_filter_arg *parent, struct tep_filter_arg *old_child,
		struct tep_filter_arg *arg, char *error_str)
{
	struct tep_filter_arg *other_child;
	struct tep_filter_arg **ptr;

	if (parent->type != TEP_FILTER_ARG_OP &&
	    arg->type != TEP_FILTER_ARG_OP) {
		show_error(error_str, "can not reparent other than OP");
		return TEP_ERRNO__REPARENT_NOT_OP;
	}

	/* Get the sibling */
	if (old_child->op.right == arg) {
		ptr = &old_child->op.right;
		other_child = old_child->op.left;
	} else if (old_child->op.left == arg) {
		ptr = &old_child->op.left;
		other_child = old_child->op.right;
	} else {
		show_error(error_str, "Error in reparent op, find other child");
		return TEP_ERRNO__REPARENT_FAILED;
	}

	/* Detach arg from old_child */
	*ptr = NULL;

	/* Check for root */
	if (parent == old_child) {
		free_arg(other_child);
		*parent = *arg;
		/* Free arg without recussion */
		free(arg);
		return 0;
	}

	if (parent->op.right == old_child)
		ptr = &parent->op.right;
	else if (parent->op.left == old_child)
		ptr = &parent->op.left;
	else {
		show_error(error_str, "Error in reparent op");
		return TEP_ERRNO__REPARENT_FAILED;
	}

	*ptr = arg;

	free_arg(old_child);
	return 0;
}

/* Returns either filter_vals (success) or tep_errno (failfure) */
static int test_arg(struct tep_filter_arg *parent, struct tep_filter_arg *arg,
		    char *error_str)
{
	int lval, rval;

	switch (arg->type) {

		/* bad case */
	case TEP_FILTER_ARG_BOOLEAN:
		return FILTER_VAL_FALSE + arg->boolean.value;

		/* good cases: */
	case TEP_FILTER_ARG_STR:
	case TEP_FILTER_ARG_VALUE:
	case TEP_FILTER_ARG_FIELD:
		return FILTER_VAL_NORM;

	case TEP_FILTER_ARG_EXP:
		lval = test_arg(arg, arg->exp.left, error_str);
		if (lval != FILTER_VAL_NORM)
			return lval;
		rval = test_arg(arg, arg->exp.right, error_str);
		if (rval != FILTER_VAL_NORM)
			return rval;
		return FILTER_VAL_NORM;

	case TEP_FILTER_ARG_NUM:
		lval = test_arg(arg, arg->num.left, error_str);
		if (lval != FILTER_VAL_NORM)
			return lval;
		rval = test_arg(arg, arg->num.right, error_str);
		if (rval != FILTER_VAL_NORM)
			return rval;
		return FILTER_VAL_NORM;

	case TEP_FILTER_ARG_OP:
		if (arg->op.type != TEP_FILTER_OP_NOT) {
			lval = test_arg(arg, arg->op.left, error_str);
			switch (lval) {
			case FILTER_VAL_NORM:
				break;
			case FILTER_VAL_TRUE:
				if (arg->op.type == TEP_FILTER_OP_OR)
					return FILTER_VAL_TRUE;
				rval = test_arg(arg, arg->op.right, error_str);
				if (rval != FILTER_VAL_NORM)
					return rval;

				return reparent_op_arg(parent, arg, arg->op.right,
						       error_str);

			case FILTER_VAL_FALSE:
				if (arg->op.type == TEP_FILTER_OP_AND)
					return FILTER_VAL_FALSE;
				rval = test_arg(arg, arg->op.right, error_str);
				if (rval != FILTER_VAL_NORM)
					return rval;

				return reparent_op_arg(parent, arg, arg->op.right,
						       error_str);

			default:
				return lval;
			}
		}

		rval = test_arg(arg, arg->op.right, error_str);
		switch (rval) {
		case FILTER_VAL_NORM:
		default:
			break;

		case FILTER_VAL_TRUE:
			if (arg->op.type == TEP_FILTER_OP_OR)
				return FILTER_VAL_TRUE;
			if (arg->op.type == TEP_FILTER_OP_NOT)
				return FILTER_VAL_FALSE;

			return reparent_op_arg(parent, arg, arg->op.left,
					       error_str);

		case FILTER_VAL_FALSE:
			if (arg->op.type == TEP_FILTER_OP_AND)
				return FILTER_VAL_FALSE;
			if (arg->op.type == TEP_FILTER_OP_NOT)
				return FILTER_VAL_TRUE;

			return reparent_op_arg(parent, arg, arg->op.left,
					       error_str);
		}

		return rval;
	default:
		show_error(error_str, "bad arg in filter tree");
		return TEP_ERRNO__BAD_FILTER_ARG;
	}
	return FILTER_VAL_NORM;
}

/* Remove any unknown event fields */
static int collapse_tree(struct tep_filter_arg *arg,
			 struct tep_filter_arg **arg_collapsed, char *error_str)
{
	int ret;

	ret = test_arg(arg, arg, error_str);
	switch (ret) {
	case FILTER_VAL_NORM:
		break;

	case FILTER_VAL_TRUE:
	case FILTER_VAL_FALSE:
		free_arg(arg);
		arg = allocate_arg();
		if (arg) {
			arg->type = TEP_FILTER_ARG_BOOLEAN;
			arg->boolean.value = ret == FILTER_VAL_TRUE;
		} else {
			show_error(error_str, "Failed to allocate filter arg");
			ret = TEP_ERRNO__MEM_ALLOC_FAILED;
		}
		break;

	default:
		/* test_arg() already set the error_str */
		free_arg(arg);
		arg = NULL;
		break;
	}

	*arg_collapsed = arg;
	return ret;
}

static enum tep_errno
process_filter(struct tep_event *event, struct tep_filter_arg **parg,
	       char *error_str, int not)
{
	enum tep_event_type type;
	char *token = NULL;
	struct tep_filter_arg *current_op = NULL;
	struct tep_filter_arg *current_exp = NULL;
	struct tep_filter_arg *left_item = NULL;
	struct tep_filter_arg *arg = NULL;
	enum op_type op_type;
	enum tep_filter_op_type btype;
	enum tep_filter_exp_type etype;
	enum tep_filter_cmp_type ctype;
	enum tep_errno ret;

	*parg = NULL;

	do {
		free(token);
		type = filter_read_token(&token);
		switch (type) {
		case TEP_EVENT_SQUOTE:
		case TEP_EVENT_DQUOTE:
		case TEP_EVENT_ITEM:
			ret = create_arg_item(event, token, type, &arg, error_str);
			if (ret < 0)
				goto fail;
			if (!left_item)
				left_item = arg;
			else if (current_exp) {
				ret = add_right(current_exp, arg, error_str);
				if (ret < 0)
					goto fail;
				left_item = NULL;
				/* Not's only one one expression */
				if (not) {
					arg = NULL;
					if (current_op)
						goto fail_syntax;
					free(token);
					*parg = current_exp;
					return 0;
				}
			} else
				goto fail_syntax;
			arg = NULL;
			break;

		case TEP_EVENT_DELIM:
			if (*token == ',') {
				show_error(error_str, "Illegal token ','");
				ret = TEP_ERRNO__ILLEGAL_TOKEN;
				goto fail;
			}

			if (*token == '(') {
				if (left_item) {
					show_error(error_str,
						   "Open paren can not come after item");
					ret = TEP_ERRNO__INVALID_PAREN;
					goto fail;
				}
				if (current_exp) {
					show_error(error_str,
						   "Open paren can not come after expression");
					ret = TEP_ERRNO__INVALID_PAREN;
					goto fail;
				}

				ret = process_filter(event, &arg, error_str, 0);
				if (ret != TEP_ERRNO__UNBALANCED_PAREN) {
					if (ret == 0) {
						show_error(error_str,
							   "Unbalanced number of '('");
						ret = TEP_ERRNO__UNBALANCED_PAREN;
					}
					goto fail;
				}
				ret = 0;

				/* A not wants just one expression */
				if (not) {
					if (current_op)
						goto fail_syntax;
					*parg = arg;
					return 0;
				}

				if (current_op)
					ret = add_right(current_op, arg, error_str);
				else
					current_exp = arg;

				if (ret < 0)
					goto fail;

			} else { /* ')' */
				if (!current_op && !current_exp)
					goto fail_syntax;

				/* Make sure everything is finished at this level */
				if (current_exp && !check_op_done(current_exp))
					goto fail_syntax;
				if (current_op && !check_op_done(current_op))
					goto fail_syntax;

				if (current_op)
					*parg = current_op;
				else
					*parg = current_exp;
				free(token);
				return TEP_ERRNO__UNBALANCED_PAREN;
			}
			break;

		case TEP_EVENT_OP:
			op_type = process_op(token, &btype, &ctype, &etype);

			/* All expect a left arg except for NOT */
			switch (op_type) {
			case OP_BOOL:
				/* Logic ops need a left expression */
				if (!current_exp && !current_op)
					goto fail_syntax;
				/* fall through */
			case OP_NOT:
				/* logic only processes ops and exp */
				if (left_item)
					goto fail_syntax;
				break;
			case OP_EXP:
			case OP_CMP:
				if (!left_item)
					goto fail_syntax;
				break;
			case OP_NONE:
				show_error(error_str,
					   "Unknown op token %s", token);
				ret = TEP_ERRNO__UNKNOWN_TOKEN;
				goto fail;
			}

			ret = 0;
			switch (op_type) {
			case OP_BOOL:
				arg = create_arg_op(btype);
				if (arg == NULL)
					goto fail_alloc;
				if (current_op)
					ret = add_left(arg, current_op);
				else
					ret = add_left(arg, current_exp);
				current_op = arg;
				current_exp = NULL;
				break;

			case OP_NOT:
				arg = create_arg_op(btype);
				if (arg == NULL)
					goto fail_alloc;
				if (current_op)
					ret = add_right(current_op, arg, error_str);
				if (ret < 0)
					goto fail;
				current_exp = arg;
				ret = process_filter(event, &arg, error_str, 1);
				if (ret < 0)
					goto fail;
				ret = add_right(current_exp, arg, error_str);
				if (ret < 0)
					goto fail;
				break;

			case OP_EXP:
			case OP_CMP:
				if (op_type == OP_EXP)
					arg = create_arg_exp(etype);
				else
					arg = create_arg_cmp(ctype);
				if (arg == NULL)
					goto fail_alloc;

				if (current_op)
					ret = add_right(current_op, arg, error_str);
				if (ret < 0)
					goto fail;
				ret = add_left(arg, left_item);
				if (ret < 0) {
					arg = NULL;
					goto fail_syntax;
				}
				current_exp = arg;
				break;
			default:
				break;
			}
			arg = NULL;
			if (ret < 0)
				goto fail_syntax;
			break;
		case TEP_EVENT_NONE:
			break;
		case TEP_EVENT_ERROR:
			goto fail_alloc;
		default:
			goto fail_syntax;
		}
	} while (type != TEP_EVENT_NONE);

	if (!current_op && !current_exp)
		goto fail_syntax;

	if (!current_op)
		current_op = current_exp;

	ret = collapse_tree(current_op, parg, error_str);
	/* collapse_tree() may free current_op, and updates parg accordingly */
	current_op = NULL;
	if (ret < 0)
		goto fail;

	free(token);
	return 0;

 fail_alloc:
	show_error(error_str, "failed to allocate filter arg");
	ret = TEP_ERRNO__MEM_ALLOC_FAILED;
	goto fail;
 fail_syntax:
	show_error(error_str, "Syntax error");
	ret = TEP_ERRNO__SYNTAX_ERROR;
 fail:
	free_arg(current_op);
	free_arg(current_exp);
	free_arg(arg);
	free(token);
	return ret;
}

static enum tep_errno
process_event(struct tep_event *event, const char *filter_str,
	      struct tep_filter_arg **parg, char *error_str)
{
	int ret;

	init_input_buf(filter_str, strlen(filter_str));

	ret = process_filter(event, parg, error_str, 0);
	if (ret < 0)
		return ret;

	/* If parg is NULL, then make it into FALSE */
	if (!*parg) {
		*parg = allocate_arg();
		if (*parg == NULL)
			return TEP_ERRNO__MEM_ALLOC_FAILED;

		(*parg)->type = TEP_FILTER_ARG_BOOLEAN;
		(*parg)->boolean.value = TEP_FILTER_FALSE;
	}

	return 0;
}

static enum tep_errno
filter_event(struct tep_event_filter *filter, struct tep_event *event,
	     const char *filter_str, char *error_str)
{
	struct tep_filter_type *filter_type;
	struct tep_filter_arg *arg;
	enum tep_errno ret;

	if (filter_str) {
		ret = process_event(event, filter_str, &arg, error_str);
		if (ret < 0)
			return ret;

	} else {
		/* just add a TRUE arg */
		arg = allocate_arg();
		if (arg == NULL)
			return TEP_ERRNO__MEM_ALLOC_FAILED;

		arg->type = TEP_FILTER_ARG_BOOLEAN;
		arg->boolean.value = TEP_FILTER_TRUE;
	}

	filter_type = add_filter_type(filter, event->id);
	if (filter_type == NULL) {
		free_arg(arg);
		return TEP_ERRNO__MEM_ALLOC_FAILED;
	}

	if (filter_type->filter)
		free_arg(filter_type->filter);
	filter_type->filter = arg;

	return 0;
}

static void filter_init_error_buf(struct tep_event_filter *filter)
{
	/* clear buffer to reset show error */
	init_input_buf("", 0);
	filter->error_buffer[0] = '\0';
}

/**
 * tep_filter_add_filter_str - add a new filter
 * @filter: the event filter to add to
 * @filter_str: the filter string that contains the filter
 *
 * Returns 0 if the filter was successfully added or a
 * negative error code.  Use tep_filter_strerror() to see
 * actual error message in case of error.
 */
enum tep_errno tep_filter_add_filter_str(struct tep_event_filter *filter,
					 const char *filter_str)
{
	struct tep_handle *tep = filter->tep;
	struct event_list *event;
	struct event_list *events = NULL;
	const char *filter_start;
	const char *next_event;
	char *this_event;
	char *event_name = NULL;
	char *sys_name = NULL;
	char *sp;
	enum tep_errno rtn = 0; /* TEP_ERRNO__SUCCESS */
	int len;
	int ret;

	filter_init_error_buf(filter);

	filter_start = strchr(filter_str, ':');
	if (filter_start)
		len = filter_start - filter_str;
	else
		len = strlen(filter_str);

	do {
		next_event = strchr(filter_str, ',');
		if (next_event &&
		    (!filter_start || next_event < filter_start))
			len = next_event - filter_str;
		else if (filter_start)
			len = filter_start - filter_str;
		else
			len = strlen(filter_str);

		this_event = malloc(len + 1);
		if (this_event == NULL) {
			/* This can only happen when events is NULL, but still */
			free_events(events);
			return TEP_ERRNO__MEM_ALLOC_FAILED;
		}
		memcpy(this_event, filter_str, len);
		this_event[len] = 0;

		if (next_event)
			next_event++;

		filter_str = next_event;

		sys_name = strtok_r(this_event, "/", &sp);
		event_name = strtok_r(NULL, "/", &sp);

		if (!sys_name) {
			/* This can only happen when events is NULL, but still */
			free_events(events);
			free(this_event);
			return TEP_ERRNO__FILTER_NOT_FOUND;
		}

		/* Find this event */
		ret = find_event(tep, &events, strim(sys_name), strim(event_name));
		if (ret < 0) {
			free_events(events);
			free(this_event);
			return ret;
		}
		free(this_event);
	} while (filter_str);

	/* Skip the ':' */
	if (filter_start)
		filter_start++;

	/* filter starts here */
	for (event = events; event; event = event->next) {
		ret = filter_event(filter, event->event, filter_start,
				   filter->error_buffer);
		/* Failures are returned if a parse error happened */
		if (ret < 0)
			rtn = ret;

		if (ret >= 0 && tep->test_filters) {
			char *test;
			test = tep_filter_make_string(filter, event->event->id);
			if (test) {
				printf(" '%s: %s'\n", event->event->name, test);
				free(test);
			}
		}
	}

	free_events(events);

	return rtn;
}

static void free_filter_type(struct tep_filter_type *filter_type)
{
	free_arg(filter_type->filter);
}

/**
 * tep_filter_strerror - fill error message in a buffer
 * @filter: the event filter contains error
 * @err: the error code
 * @buf: the buffer to be filled in
 * @buflen: the size of the buffer
 *
 * Returns 0 if message was filled successfully, -1 if error
 */
int tep_filter_strerror(struct tep_event_filter *filter, enum tep_errno err,
			char *buf, size_t buflen)
{
	if (err <= __TEP_ERRNO__START || err >= __TEP_ERRNO__END)
		return -1;

	if (strlen(filter->error_buffer) > 0) {
		size_t len = snprintf(buf, buflen, "%s", filter->error_buffer);

		if (len > buflen)
			return -1;
		return 0;
	}

	return tep_strerror(filter->tep, err, buf, buflen);
}

/**
 * tep_filter_remove_event - remove a filter for an event
 * @filter: the event filter to remove from
 * @event_id: the event to remove a filter for
 *
 * Removes the filter saved for an event defined by @event_id
 * from the @filter.
 *
 * Returns 1: if an event was removed
 *   0: if the event was not found
 */
int tep_filter_remove_event(struct tep_event_filter *filter,
			    int event_id)
{
	struct tep_filter_type *filter_type;
	unsigned long len;

	if (!filter->filters)
		return 0;

	filter_type = find_filter_type(filter, event_id);

	if (!filter_type)
		return 0;

	free_filter_type(filter_type);

	/* The filter_type points into the event_filters array */
	len = (unsigned long)(filter->event_filters + filter->filters) -
		(unsigned long)(filter_type + 1);

	memmove(filter_type, filter_type + 1, len);
	filter->filters--;

	memset(&filter->event_filters[filter->filters], 0,
	       sizeof(*filter_type));

	return 1;
}

/**
 * tep_filter_reset - clear all filters in a filter
 * @filter: the event filter to reset
 *
 * Removes all filters from a filter and resets it.
 */
void tep_filter_reset(struct tep_event_filter *filter)
{
	int i;

	for (i = 0; i < filter->filters; i++)
		free_filter_type(&filter->event_filters[i]);

	free(filter->event_filters);
	filter->filters = 0;
	filter->event_filters = NULL;
}

void tep_filter_free(struct tep_event_filter *filter)
{
	tep_unref(filter->tep);

	tep_filter_reset(filter);

	free(filter);
}

static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg);

static int copy_filter_type(struct tep_event_filter *filter,
			    struct tep_event_filter *source,
			    struct tep_filter_type *filter_type)
{
	struct tep_filter_arg *arg;
	struct tep_event *event;
	const char *sys;
	const char *name;
	char *str;

	/* Can't assume that the tep's are the same */
	sys = filter_type->event->system;
	name = filter_type->event->name;
	event = tep_find_event_by_name(filter->tep, sys, name);
	if (!event)
		return -1;

	str = arg_to_str(source, filter_type->filter);
	if (!str)
		return -1;

	if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) {
		/* Add trivial event */
		arg = allocate_arg();
		if (arg == NULL) {
			free(str);
			return -1;
		}

		arg->type = TEP_FILTER_ARG_BOOLEAN;
		if (strcmp(str, "TRUE") == 0)
			arg->boolean.value = 1;
		else
			arg->boolean.value = 0;

		filter_type = add_filter_type(filter, event->id);
		if (filter_type == NULL) {
			free(str);
			free_arg(arg);
			return -1;
		}

		filter_type->filter = arg;

		free(str);
		return 0;
	}

	filter_event(filter, event, str, NULL);
	free(str);

	return 0;
}

/**
 * tep_filter_copy - copy a filter using another filter
 * @dest - the filter to copy to
 * @source - the filter to copy from
 *
 * Returns 0 on success and -1 if not all filters were copied
 */
int tep_filter_copy(struct tep_event_filter *dest, struct tep_event_filter *source)
{
	int ret = 0;
	int i;

	tep_filter_reset(dest);

	for (i = 0; i < source->filters; i++) {
		if (copy_filter_type(dest, source, &source->event_filters[i]))
			ret = -1;
	}
	return ret;
}

static int test_filter(struct tep_event *event, struct tep_filter_arg *arg,
		       struct tep_record *record, enum tep_errno *err);

static const char *
get_comm(struct tep_event *event, struct tep_record *record)
{
	const char *comm;
	int pid;

	pid = tep_data_pid(event->tep, record);
	comm = tep_data_comm_from_pid(event->tep, pid);
	return comm;
}

static unsigned long long
get_value(struct tep_event *event,
	  struct tep_format_field *field, struct tep_record *record)
{
	unsigned long long val;

	/* Handle our dummy "comm" field */
	if (field == &comm) {
		const char *name;

		name = get_comm(event, record);
		return (unsigned long)name;
	}

	/* Handle our dummy "cpu" field */
	if (field == &cpu)
		return record->cpu;

	tep_read_number_field(field, record->data, &val);

	if (!(field->flags & TEP_FIELD_IS_SIGNED))
		return val;

	switch (field->size) {
	case 1:
		return (char)val;
	case 2:
		return (short)val;
	case 4:
		return (int)val;
	case 8:
		return (long long)val;
	}
	return val;
}

static unsigned long long
get_arg_value(struct tep_event *event, struct tep_filter_arg *arg,
	      struct tep_record *record, enum tep_errno *err);

static unsigned long long
get_exp_value(struct tep_event *event, struct tep_filter_arg *arg,
	      struct tep_record *record, enum tep_errno *err)
{
	unsigned long long lval, rval;

	lval = get_arg_value(event, arg->exp.left, record, err);
	rval = get_arg_value(event, arg->exp.right, record, err);

	if (*err) {
		/*
		 * There was an error, no need to process anymore.
		 */
		return 0;
	}

	switch (arg->exp.type) {
	case TEP_FILTER_EXP_ADD:
		return lval + rval;

	case TEP_FILTER_EXP_SUB:
		return lval - rval;

	case TEP_FILTER_EXP_MUL:
		return lval * rval;

	case TEP_FILTER_EXP_DIV:
		return lval / rval;

	case TEP_FILTER_EXP_MOD:
		return lval % rval;

	case TEP_FILTER_EXP_RSHIFT:
		return lval >> rval;

	case TEP_FILTER_EXP_LSHIFT:
		return lval << rval;

	case TEP_FILTER_EXP_AND:
		return lval & rval;

	case TEP_FILTER_EXP_OR:
		return lval | rval;

	case TEP_FILTER_EXP_XOR:
		return lval ^ rval;

	case TEP_FILTER_EXP_NOT:
	default:
		if (!*err)
			*err = TEP_ERRNO__INVALID_EXP_TYPE;
	}
	return 0;
}

static unsigned long long
get_arg_value(struct tep_event *event, struct tep_filter_arg *arg,
	      struct tep_record *record, enum tep_errno *err)
{
	switch (arg->type) {
	case TEP_FILTER_ARG_FIELD:
		return get_value(event, arg->field.field, record);

	case TEP_FILTER_ARG_VALUE:
		if (arg->value.type != TEP_FILTER_NUMBER) {
			if (!*err)
				*err = TEP_ERRNO__NOT_A_NUMBER;
		}
		return arg->value.val;

	case TEP_FILTER_ARG_EXP:
		return get_exp_value(event, arg, record, err);

	default:
		if (!*err)
			*err = TEP_ERRNO__INVALID_ARG_TYPE;
	}
	return 0;
}

static int test_num(struct tep_event *event, struct tep_filter_arg *arg,
		    struct tep_record *record, enum tep_errno *err)
{
	unsigned long long lval, rval;

	lval = get_arg_value(event, arg->num.left, record, err);
	rval = get_arg_value(event, arg->num.right, record, err);

	if (*err) {
		/*
		 * There was an error, no need to process anymore.
		 */
		return 0;
	}

	switch (arg->num.type) {
	case TEP_FILTER_CMP_EQ:
		return lval == rval;

	case TEP_FILTER_CMP_NE:
		return lval != rval;

	case TEP_FILTER_CMP_GT:
		return lval > rval;

	case TEP_FILTER_CMP_LT:
		return lval < rval;

	case TEP_FILTER_CMP_GE:
		return lval >= rval;

	case TEP_FILTER_CMP_LE:
		return lval <= rval;

	default:
		if (!*err)
			*err = TEP_ERRNO__ILLEGAL_INTEGER_CMP;
		return 0;
	}
}

static const char *get_field_str(struct tep_filter_arg *arg, struct tep_record *record)
{
	struct tep_event *event;
	struct tep_handle *tep;
	unsigned long long addr;
	const char *val = NULL;
	unsigned int size;
	char hex[64];

	/* If the field is not a string convert it */
	if (arg->str.field->flags & TEP_FIELD_IS_STRING) {
		val = record->data + arg->str.field->offset;
		size = arg->str.field->size;

		if (arg->str.field->flags & TEP_FIELD_IS_DYNAMIC) {
			addr = *(unsigned int *)val;
			val = record->data + (addr & 0xffff);
			size = addr >> 16;
		}

		/*
		 * We need to copy the data since we can't be sure the field
		 * is null terminated.
		 */
		if (*(val + size - 1)) {
			/* copy it */
			memcpy(arg->str.buffer, val, arg->str.field->size);
			/* the buffer is already NULL terminated */
			val = arg->str.buffer;
		}

	} else {
		event = arg->str.field->event;
		tep = event->tep;
		addr = get_value(event, arg->str.field, record);

		if (arg->str.field->flags & (TEP_FIELD_IS_POINTER | TEP_FIELD_IS_LONG))
			/* convert to a kernel symbol */
			val = tep_find_function(tep, addr);

		if (val == NULL) {
			/* just use the hex of the string name */
			snprintf(hex, 64, "0x%llx", addr);
			val = hex;
		}
	}

	return val;
}

static int test_str(struct tep_event *event, struct tep_filter_arg *arg,
		    struct tep_record *record, enum tep_errno *err)
{
	const char *val;

	if (arg->str.field == &comm)
		val = get_comm(event, record);
	else
		val = get_field_str(arg, record);

	switch (arg->str.type) {
	case TEP_FILTER_CMP_MATCH:
		return strcmp(val, arg->str.val) == 0;

	case TEP_FILTER_CMP_NOT_MATCH:
		return strcmp(val, arg->str.val) != 0;

	case TEP_FILTER_CMP_REGEX:
		/* Returns zero on match */
		return !regexec(&arg->str.reg, val, 0, NULL, 0);

	case TEP_FILTER_CMP_NOT_REGEX:
		return regexec(&arg->str.reg, val, 0, NULL, 0);

	default:
		if (!*err)
			*err = TEP_ERRNO__ILLEGAL_STRING_CMP;
		return 0;
	}
}

static int test_op(struct tep_event *event, struct tep_filter_arg *arg,
		   struct tep_record *record, enum tep_errno *err)
{
	switch (arg->op.type) {
	case TEP_FILTER_OP_AND:
		return test_filter(event, arg->op.left, record, err) &&
			test_filter(event, arg->op.right, record, err);

	case TEP_FILTER_OP_OR:
		return test_filter(event, arg->op.left, record, err) ||
			test_filter(event, arg->op.right, record, err);

	case TEP_FILTER_OP_NOT:
		return !test_filter(event, arg->op.right, record, err);

	default:
		if (!*err)
			*err = TEP_ERRNO__INVALID_OP_TYPE;
		return 0;
	}
}

static int test_filter(struct tep_event *event, struct tep_filter_arg *arg,
		       struct tep_record *record, enum tep_errno *err)
{
	if (*err) {
		/*
		 * There was an error, no need to process anymore.
		 */
		return 0;
	}

	switch (arg->type) {
	case TEP_FILTER_ARG_BOOLEAN:
		/* easy case */
		return arg->boolean.value;

	case TEP_FILTER_ARG_OP:
		return test_op(event, arg, record, err);

	case TEP_FILTER_ARG_NUM:
		return test_num(event, arg, record, err);

	case TEP_FILTER_ARG_STR:
		return test_str(event, arg, record, err);

	case TEP_FILTER_ARG_EXP:
	case TEP_FILTER_ARG_VALUE:
	case TEP_FILTER_ARG_FIELD:
		/*
		 * Expressions, fields and values evaluate
		 * to true if they return non zero
		 */
		return !!get_arg_value(event, arg, record, err);

	default:
		if (!*err)
			*err = TEP_ERRNO__INVALID_ARG_TYPE;
		return 0;
	}
}

/**
 * tep_event_filtered - return true if event has filter
 * @filter: filter struct with filter information
 * @event_id: event id to test if filter exists
 *
 * Returns 1 if filter found for @event_id
 *   otherwise 0;
 */
int tep_event_filtered(struct tep_event_filter *filter, int event_id)
{
	struct tep_filter_type *filter_type;

	if (!filter->filters)
		return 0;

	filter_type = find_filter_type(filter, event_id);

	return filter_type ? 1 : 0;
}

/**
 * tep_filter_match - test if a record matches a filter
 * @filter: filter struct with filter information
 * @record: the record to test against the filter
 *
 * Returns: match result or error code (prefixed with TEP_ERRNO__)
 * FILTER_MATCH - filter found for event and @record matches
 * FILTER_MISS  - filter found for event and @record does not match
 * FILTER_NOT_FOUND - no filter found for @record's event
 * NO_FILTER - if no filters exist
 * otherwise - error occurred during test
 */
enum tep_errno tep_filter_match(struct tep_event_filter *filter,
				struct tep_record *record)
{
	struct tep_handle *tep = filter->tep;
	struct tep_filter_type *filter_type;
	int event_id;
	int ret;
	enum tep_errno err = 0;

	filter_init_error_buf(filter);

	if (!filter->filters)
		return TEP_ERRNO__NO_FILTER;

	event_id = tep_data_type(tep, record);

	filter_type = find_filter_type(filter, event_id);
	if (!filter_type)
		return TEP_ERRNO__FILTER_NOT_FOUND;

	ret = test_filter(filter_type->event, filter_type->filter, record, &err);
	if (err)
		return err;

	return ret ? TEP_ERRNO__FILTER_MATCH : TEP_ERRNO__FILTER_MISS;
}

static char *op_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
{
	char *str = NULL;
	char *left = NULL;
	char *right = NULL;
	char *op = NULL;
	int left_val = -1;
	int right_val = -1;
	int val;

	switch (arg->op.type) {
	case TEP_FILTER_OP_AND:
		op = "&&";
		/* fall through */
	case TEP_FILTER_OP_OR:
		if (!op)
			op = "||";

		left = arg_to_str(filter, arg->op.left);
		right = arg_to_str(filter, arg->op.right);
		if (!left || !right)
			break;

		/* Try to consolidate boolean values */
		if (strcmp(left, "TRUE") == 0)
			left_val = 1;
		else if (strcmp(left, "FALSE") == 0)
			left_val = 0;

		if (strcmp(right, "TRUE") == 0)
			right_val = 1;
		else if (strcmp(right, "FALSE") == 0)
			right_val = 0;

		if (left_val >= 0) {
			if ((arg->op.type == TEP_FILTER_OP_AND && !left_val) ||
			    (arg->op.type == TEP_FILTER_OP_OR && left_val)) {
				/* Just return left value */
				str = left;
				left = NULL;
				break;
			}
			if (right_val >= 0) {
				/* just evaluate this. */
				val = 0;
				switch (arg->op.type) {
				case TEP_FILTER_OP_AND:
					val = left_val && right_val;
					break;
				case TEP_FILTER_OP_OR:
					val = left_val || right_val;
					break;
				default:
					break;
				}
				if (asprintf(&str, val ? "TRUE" : "FALSE") < 0)
					str = NULL;
				break;
			}
		}
		if (right_val >= 0) {
			if ((arg->op.type == TEP_FILTER_OP_AND && !right_val) ||
			    (arg->op.type == TEP_FILTER_OP_OR && right_val)) {
				/* Just return right value */
				str = right;
				right = NULL;
				break;
			}
			/* The right value is meaningless */
			str = left;
			left = NULL;
			break;
		}

		if (asprintf(&str, "(%s) %s (%s)", left, op, right) < 0)
			str = NULL;
		break;

	case TEP_FILTER_OP_NOT:
		op = "!";
		right = arg_to_str(filter, arg->op.right);
		if (!right)
			break;

		/* See if we can consolidate */
		if (strcmp(right, "TRUE") == 0)
			right_val = 1;
		else if (strcmp(right, "FALSE") == 0)
			right_val = 0;
		if (right_val >= 0) {
			/* just return the opposite */
			if (asprintf(&str, right_val ? "FALSE" : "TRUE") < 0)
				str = NULL;
			break;
		}
		if (asprintf(&str, "%s(%s)", op, right) < 0)
			str = NULL;
		break;

	default:
		/* ?? */
		break;
	}
	free(left);
	free(right);
	return str;
}

static char *val_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
{
	char *str = NULL;

	if (asprintf(&str, "%lld", arg->value.val) < 0)
		str = NULL;

	return str;
}

static char *field_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
{
	return strdup(arg->field.field->name);
}

static char *exp_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
{
	char *lstr;
	char *rstr;
	char *op;
	char *str = NULL;

	lstr = arg_to_str(filter, arg->exp.left);
	rstr = arg_to_str(filter, arg->exp.right);
	if (!lstr || !rstr)
		goto out;

	switch (arg->exp.type) {
	case TEP_FILTER_EXP_ADD:
		op = "+";
		break;
	case TEP_FILTER_EXP_SUB:
		op = "-";
		break;
	case TEP_FILTER_EXP_MUL:
		op = "*";
		break;
	case TEP_FILTER_EXP_DIV:
		op = "/";
		break;
	case TEP_FILTER_EXP_MOD:
		op = "%";
		break;
	case TEP_FILTER_EXP_RSHIFT:
		op = ">>";
		break;
	case TEP_FILTER_EXP_LSHIFT:
		op = "<<";
		break;
	case TEP_FILTER_EXP_AND:
		op = "&";
		break;
	case TEP_FILTER_EXP_OR:
		op = "|";
		break;
	case TEP_FILTER_EXP_XOR:
		op = "^";
		break;
	default:
		op = "[ERROR IN EXPRESSION TYPE]";
		break;
	}

	if (asprintf(&str, "%s %s %s", lstr, op, rstr) < 0)
		str = NULL;
out:
	free(lstr);
	free(rstr);

	return str;
}

static char *num_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
{
	char *lstr;
	char *rstr;
	char *str = NULL;
	char *op = NULL;

	lstr = arg_to_str(filter, arg->num.left);
	rstr = arg_to_str(filter, arg->num.right);
	if (!lstr || !rstr)
		goto out;

	switch (arg->num.type) {
	case TEP_FILTER_CMP_EQ:
		op = "==";
		/* fall through */
	case TEP_FILTER_CMP_NE:
		if (!op)
			op = "!=";
		/* fall through */
	case TEP_FILTER_CMP_GT:
		if (!op)
			op = ">";
		/* fall through */
	case TEP_FILTER_CMP_LT:
		if (!op)
			op = "<";
		/* fall through */
	case TEP_FILTER_CMP_GE:
		if (!op)
			op = ">=";
		/* fall through */
	case TEP_FILTER_CMP_LE:
		if (!op)
			op = "<=";

		if (asprintf(&str, "%s %s %s", lstr, op, rstr) < 0)
			str = NULL;
		break;

	default:
		/* ?? */
		break;
	}

out:
	free(lstr);
	free(rstr);
	return str;
}

static char *str_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
{
	char *str = NULL;
	char *op = NULL;

	switch (arg->str.type) {
	case TEP_FILTER_CMP_MATCH:
		op = "==";
		/* fall through */
	case TEP_FILTER_CMP_NOT_MATCH:
		if (!op)
			op = "!=";
		/* fall through */
	case TEP_FILTER_CMP_REGEX:
		if (!op)
			op = "=~";
		/* fall through */
	case TEP_FILTER_CMP_NOT_REGEX:
		if (!op)
			op = "!~";

		if (asprintf(&str, "%s %s \"%s\"",
			 arg->str.field->name, op, arg->str.val) < 0)
			str = NULL;
		break;

	default:
		/* ?? */
		break;
	}
	return str;
}

static char *arg_to_str(struct tep_event_filter *filter, struct tep_filter_arg *arg)
{
	char *str = NULL;

	switch (arg->type) {
	case TEP_FILTER_ARG_BOOLEAN:
		if (asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE") < 0)
			str = NULL;
		return str;

	case TEP_FILTER_ARG_OP:
		return op_to_str(filter, arg);

	case TEP_FILTER_ARG_NUM:
		return num_to_str(filter, arg);

	case TEP_FILTER_ARG_STR:
		return str_to_str(filter, arg);

	case TEP_FILTER_ARG_VALUE:
		return val_to_str(filter, arg);

	case TEP_FILTER_ARG_FIELD:
		return field_to_str(filter, arg);

	case TEP_FILTER_ARG_EXP:
		return exp_to_str(filter, arg);

	default:
		/* ?? */
		return NULL;
	}

}

/**
 * tep_filter_make_string - return a string showing the filter
 * @filter: filter struct with filter information
 * @event_id: the event id to return the filter string with
 *
 * Returns a string that displays the filter contents.
 *  This string must be freed with free(str).
 *  NULL is returned if no filter is found or allocation failed.
 */
char *
tep_filter_make_string(struct tep_event_filter *filter, int event_id)
{
	struct tep_filter_type *filter_type;

	if (!filter->filters)
		return NULL;

	filter_type = find_filter_type(filter, event_id);

	if (!filter_type)
		return NULL;

	return arg_to_str(filter, filter_type->filter);
}

/**
 * tep_filter_compare - compare two filters and return if they are the same
 * @filter1: Filter to compare with @filter2
 * @filter2: Filter to compare with @filter1
 *
 * Returns:
 *  1 if the two filters hold the same content.
 *  0 if they do not.
 */
int tep_filter_compare(struct tep_event_filter *filter1, struct tep_event_filter *filter2)
{
	struct tep_filter_type *filter_type1;
	struct tep_filter_type *filter_type2;
	char *str1, *str2;
	int result;
	int i;

	/* Do the easy checks first */
	if (filter1->filters != filter2->filters)
		return 0;
	if (!filter1->filters && !filter2->filters)
		return 1;

	/*
	 * Now take a look at each of the events to see if they have the same
	 * filters to them.
	 */
	for (i = 0; i < filter1->filters; i++) {
		filter_type1 = &filter1->event_filters[i];
		filter_type2 = find_filter_type(filter2, filter_type1->event_id);
		if (!filter_type2)
			break;
		if (filter_type1->filter->type != filter_type2->filter->type)
			break;
		/* The best way to compare complex filters is with strings */
		str1 = arg_to_str(filter1, filter_type1->filter);
		str2 = arg_to_str(filter2, filter_type2->filter);
		if (str1 && str2)
			result = strcmp(str1, str2) != 0;
		else
			/* bail out if allocation fails */
			result = 1;

		free(str1);
		free(str2);
		if (result)
			break;
	}

	if (i < filter1->filters)
		return 0;
	return 1;
}

