/*
 * This file is part of the ZFS Event Daemon (ZED)
 * for ZFS on Linux (ZoL) <http://zfsonlinux.org/>.
 * Developed at Lawrence Livermore National Laboratory (LLNL-CODE-403049).
 * Copyright (C) 2013-2014 Lawrence Livermore National Security, LLC.
 * Refer to the ZoL git commit log for authoritative copyright attribution.
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License Version 1.0 (CDDL-1.0).
 * You can obtain a copy of the license from the top-level file
 * "OPENSOLARIS.LICENSE" or at <http://opensource.org/licenses/CDDL-1.0>.
 * You may not use this file except in compliance with the license.
 */

#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/avl.h>
#include <sys/sysmacros.h>
#include "zed_strings.h"

struct zed_strings {
	avl_tree_t tree;
	avl_node_t *iteratorp;
};

struct zed_strings_node {
	avl_node_t node;
	char *key;
	char *val;
};

typedef struct zed_strings_node zed_strings_node_t;

/*
 * Compare zed_strings_node_t nodes [x1] and [x2].
 * As required for the AVL tree, return -1 for <, 0 for ==, and +1 for >.
 */
static int
_zed_strings_node_compare(const void *x1, const void *x2)
{
	const char *s1;
	const char *s2;
	int rv;

	assert(x1 != NULL);
	assert(x2 != NULL);

	s1 = ((const zed_strings_node_t *) x1)->key;
	assert(s1 != NULL);
	s2 = ((const zed_strings_node_t *) x2)->key;
	assert(s2 != NULL);
	rv = strcmp(s1, s2);

	if (rv < 0)
		return (-1);

	if (rv > 0)
		return (1);

	return (0);
}

/*
 * Return a new string container, or NULL on error.
 */
zed_strings_t *
zed_strings_create(void)
{
	zed_strings_t *zsp;

	zsp = calloc(1, sizeof (*zsp));
	if (!zsp)
		return (NULL);

	avl_create(&zsp->tree, _zed_strings_node_compare,
	    sizeof (zed_strings_node_t), offsetof(zed_strings_node_t, node));

	zsp->iteratorp = NULL;
	return (zsp);
}

/*
 * Destroy the string node [np].
 */
static void
_zed_strings_node_destroy(zed_strings_node_t *np)
{
	if (!np)
		return;

	if (np->key) {
		if (np->key != np->val)
			free(np->key);
		np->key = NULL;
	}
	if (np->val) {
		free(np->val);
		np->val = NULL;
	}
	free(np);
}

/*
 * Return a new string node for storing the string [val], or NULL on error.
 * If [key] is specified, it will be used to index the node; otherwise,
 * the string [val] will be used.
 */
zed_strings_node_t *
_zed_strings_node_create(const char *key, const char *val)
{
	zed_strings_node_t *np;

	assert(val != NULL);

	np = calloc(1, sizeof (*np));
	if (!np)
		return (NULL);

	np->val = strdup(val);
	if (!np->val)
		goto nomem;

	if (key) {
		np->key = strdup(key);
		if (!np->key)
			goto nomem;
	} else {
		np->key = np->val;
	}
	return (np);

nomem:
	_zed_strings_node_destroy(np);
	return (NULL);
}

/*
 * Destroy the string container [zsp] and all nodes within.
 */
void
zed_strings_destroy(zed_strings_t *zsp)
{
	void *cookie;
	zed_strings_node_t *np;

	if (!zsp)
		return;

	cookie = NULL;
	while ((np = avl_destroy_nodes(&zsp->tree, &cookie)))
		_zed_strings_node_destroy(np);

	avl_destroy(&zsp->tree);
	free(zsp);
}

/*
 * Add a copy of the string [s] indexed by [key] to the container [zsp].
 * If [key] already exists within the container [zsp], it will be replaced
 * with the new string [s].
 * If [key] is NULL, the string [s] will be used as the key.
 * Return 0 on success, or -1 on error.
 */
int
zed_strings_add(zed_strings_t *zsp, const char *key, const char *s)
{
	zed_strings_node_t *newp, *oldp;

	if (!zsp || !s) {
		errno = EINVAL;
		return (-1);
	}
	if (key == s)
		key = NULL;

	newp = _zed_strings_node_create(key, s);
	if (!newp)
		return (-1);

	oldp = avl_find(&zsp->tree, newp, NULL);
	if (oldp) {
		avl_remove(&zsp->tree, oldp);
		_zed_strings_node_destroy(oldp);
	}
	avl_add(&zsp->tree, newp);
	return (0);
}

/*
 * Return the first string in container [zsp].
 * Return NULL if there are no strings, or on error.
 * This can be called multiple times to re-traverse [zsp].
 * XXX: Not thread-safe.
 */
const char *
zed_strings_first(zed_strings_t *zsp)
{
	if (!zsp) {
		errno = EINVAL;
		return (NULL);
	}
	zsp->iteratorp = avl_first(&zsp->tree);
	if (!zsp->iteratorp)
		return (NULL);

	return (((zed_strings_node_t *)zsp->iteratorp)->val);

}

/*
 * Return the next string in container [zsp].
 * Return NULL after the last string, or on error.
 * This must be called after zed_strings_first().
 * XXX: Not thread-safe.
 */
const char *
zed_strings_next(zed_strings_t *zsp)
{
	if (!zsp) {
		errno = EINVAL;
		return (NULL);
	}
	if (!zsp->iteratorp)
		return (NULL);

	zsp->iteratorp = AVL_NEXT(&zsp->tree, zsp->iteratorp);
	if (!zsp->iteratorp)
		return (NULL);

	return (((zed_strings_node_t *)zsp->iteratorp)->val);
}

/*
 * Return the number of strings in container [zsp], or -1 on error.
 */
int
zed_strings_count(zed_strings_t *zsp)
{
	if (!zsp) {
		errno = EINVAL;
		return (-1);
	}
	return (avl_numnodes(&zsp->tree));
}
