/*
 * Copyright (C) 2009, Steven Rostedt <srostedt@redhat.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * This program 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; version 2 of the License (not later!)
 *
 * This program 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 this program; if not,  see <http://www.gnu.org/licenses>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#include "trace-filter-hash.h"

#define FILTER_TASK_HASH_SIZE	256

struct filter_task_item *
filter_task_find_pid(struct filter_task *hash, gint pid)
{
	gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE;
	struct filter_task_item *task = hash->hash[key];

	while (task) {
		if (task->pid == pid)
			break;
		task = task->next;
	}
	return task;
}

void filter_task_add_pid(struct filter_task *hash, gint pid)
{
	gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE;
	struct filter_task_item *task;

	task = g_new0(typeof(*task), 1);
	g_assert(task);

	task->pid = pid;
	task->next = hash->hash[key];
	hash->hash[key] = task;

	hash->count++;
}

void filter_task_remove_pid(struct filter_task *hash, gint pid)
{
	gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE;
	struct filter_task_item **next = &hash->hash[key];
	struct filter_task_item *task;

	while (*next) {
		if ((*next)->pid == pid)
			break;
		next = &(*next)->next;
	}
	if (!*next)
		return;

	g_assert(hash->count);
	hash->count--;

	task = *next;

	*next = task->next;

	g_free(task);
}

void filter_task_clear(struct filter_task *hash)
{
	struct filter_task_item *task, *next;;
	gint i;

	for (i = 0; i < FILTER_TASK_HASH_SIZE; i++) {
		next = hash->hash[i];
		if (!next)
			continue;

		hash->hash[i] = NULL;
		while (next) {
			task = next;
			next = task->next;
			g_free(task);
		}
	}

	hash->count = 0;
}

struct filter_task *filter_task_hash_alloc(void)
{
	struct filter_task *hash;

	hash = g_new0(typeof(*hash), 1);
	g_assert(hash);
	hash->hash = g_new0(typeof(*hash->hash), FILTER_TASK_HASH_SIZE);

	return hash;
}

void filter_task_hash_free(struct filter_task *hash)
{
	if (!hash)
		return;

	filter_task_clear(hash);
	g_free(hash->hash);
	g_free(hash);
}

struct filter_task *filter_task_hash_copy(struct filter_task *hash)
{
	struct filter_task *new_hash;
	struct filter_task_item *task, **ptask;
	gint i;

	if (!hash)
		return NULL;

	new_hash = filter_task_hash_alloc();
	g_assert(new_hash);

	for (i = 0; i < FILTER_TASK_HASH_SIZE; i++) {
		task = hash->hash[i];
		if (!task)
			continue;

		ptask = &new_hash->hash[i];

		while (task) {

			*ptask = g_new0(typeof(*task), 1);
			g_assert(*ptask);
			**ptask = *task;

			ptask = &(*ptask)->next;
			task = task->next;
		}
	}

	new_hash->count = hash->count;

	return new_hash;
}

int *filter_task_pids(struct filter_task *hash)
{
	struct filter_task_item *task;
	int *pids;
	int count = 0;
	int i;

	if (!hash->count)
		return NULL;

	pids = malloc(sizeof(*pids) * (hash->count + 1));
	if (!pids)
		return NULL;

	for (i = 0; i < FILTER_TASK_HASH_SIZE; i++) {
		task = hash->hash[i];
		while (task) {
			pids[count++] = task->pid;
			task = task->next;
		}
	}
	pids[count] = -1;

	return pids;
}

/**
 * filter_task_compare - compare two task hashs to see if they are equal
 * @hash1: one hash to compare
 * @hash2: another hash to compare to @hash1
 *
 * Returns 1 if the two hashes are the same, 0 otherwise.
 */
int filter_task_compare(struct filter_task *hash1, struct filter_task *hash2)
{
	int *pids;
	int ret = 0;
	int i;

	/* If counts don't match, then they obviously are not the same */
	if (hash1->count != hash2->count)
		return 0;

	/* If both hashes are empty, they are the same */
	if (!hash1->count && !hash2->count)
		return 1;

	/* Now compare the pids of one hash with the other */
	pids = filter_task_pids(hash1);
	for (i = 0; pids[i] >= 0; i++) {
		if (!filter_task_find_pid(hash2, pids[i]))
			break;
	}

	if (pids[i] == -1)
		ret = 1;

	free(pids);

	return ret;
}
