/*
 *
 *  Embedded Linux library
 *
 *  Copyright (C) 2011-2014  Intel Corporation. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _GNU_SOURCE
#include <string.h>

#include "strv.h"
#include "private.h"
#include "useful.h"

/**
 * SECTION:strv
 * @short_description: String array functions
 *
 * String array functions
 */

/**
 * l_strfreev:
 * @strlist: String list to free
 *
 * Frees a list of strings
 **/
LIB_EXPORT void l_strfreev(char **strlist)
{
	l_strv_free(strlist);
}

/**
 * l_strsplit:
 * @str: String to split
 * @sep: The delimiter character
 *
 * Splits a string into pieces which do not contain the delimiter character.
 * As a special case, an empty string is returned as an empty array, e.g.
 * an array with just the NULL element.
 *
 * Note that this function only works with ASCII delimiters.
 *
 * Returns: A newly allocated %NULL terminated string array.  This array
 * should be freed using l_strfreev().
 **/
LIB_EXPORT char **l_strsplit(const char *str, const char sep)
{
	int len;
	int i;
	const char *p;
	char **ret;

	if (unlikely(!str))
		return NULL;

	if (str[0] == '\0')
		return l_new(char *, 1);

	for (p = str, len = 1; *p; p++)
		if (*p == sep)
			len += 1;

	ret = l_new(char *, len + 1);

	i = 0;
	p = str;
	len = 0;

	while (p[len]) {
		if (p[len] != sep) {
			len += 1;
			continue;
		}

		ret[i++] = l_strndup(p, len);
		p += len + 1;
		len = 0;
	}

	ret[i++] = l_strndup(p, len);

	return ret;
}

/**
 * l_strsplit_set:
 * @str: String to split
 * @separators: A set of delimiters
 *
 * Splits a string into pieces which do not contain the delimiter characters
 * that can be found in @separators.
 * As a special case, an empty string is returned as an empty array, e.g.
 * an array with just the NULL element.
 *
 * Note that this function only works with ASCII delimiters.
 *
 * Returns: A newly allocated %NULL terminated string array.  This array
 * should be freed using l_strfreev().
 **/
LIB_EXPORT char **l_strsplit_set(const char *str, const char *separators)
{
	int len;
	int i;
	const char *p;
	char **ret;
	bool sep_table[256];

	if (unlikely(!str))
		return NULL;

	if (str[0] == '\0')
		return l_new(char *, 1);

	memset(sep_table, 0, sizeof(sep_table));

	for (p = separators; *p; p++)
		sep_table[(unsigned char) *p] = true;

	for (p = str, len = 1; *p; p++)
		if (sep_table[(unsigned char) *p] == true)
			len += 1;

	ret = l_new(char *, len + 1);

	i = 0;
	p = str;
	len = 0;

	while (p[len]) {
		if (sep_table[(unsigned char) p[len]] != true) {
			len += 1;
			continue;
		}

		ret[i++] = l_strndup(p, len);
		p += len + 1;
		len = 0;
	}

	ret[i++] = l_strndup(p, len);

	return ret;
}

/**
 * l_strjoinv:
 * @str_array: a %NULL terminated array of strings to join
 * @delim: Delimiting character
 *
 * Joins strings contanied in the @str_array into one long string delimited
 * by @delim.
 *
 * Returns: A newly allocated string that should be freed using l_free()
 */
LIB_EXPORT char *l_strjoinv(char **str_array, const char delim)
{
	size_t len = 0;
	unsigned int i;
	char *ret;
	char *p;

	if (unlikely(!str_array))
		return NULL;

	if (!str_array[0])
		return l_strdup("");

	for (i = 0; str_array[i]; i++)
		len += strlen(str_array[i]);

	len += 1 + i - 1;

	ret = l_malloc(len);

	p = stpcpy(ret, str_array[0]);

	for (i = 1; str_array[i]; i++) {
		*p++ = delim;
		p = stpcpy(p, str_array[i]);
	}

	return ret;
}

/**
 * l_strv_new:
 *
 * Returns: new emptry string array
 **/
LIB_EXPORT char **l_strv_new(void)
{
	return l_new(char *, 1);
}

/**
 * l_strv_free:
 * @str_array: a %NULL terminated array of strings
 *
 * Frees strings in @str_array and @str_array itself
 **/
LIB_EXPORT void l_strv_free(char **str_array)
{
	if (likely(str_array)) {
		int i;

		for (i = 0; str_array[i]; i++)
			l_free(str_array[i]);

		l_free(str_array);
	}
}

/**
 * l_strv_length:
 * @str_array: a %NULL terminated array of strings
 *
 * Returns: the number of strings in @str_array
 */
LIB_EXPORT unsigned int l_strv_length(char **str_array)
{
	unsigned int i = 0;

	if (unlikely(!str_array))
		return 0;

	while (str_array[i])
		i += 1;

	return i;
}

/**
 * l_strv_contains:
 * @str_array: a %NULL terminated array of strings
 * @item: An item to search for, must be not %NULL
 *
 * Returns: #true if @str_array contains item
 */
LIB_EXPORT bool l_strv_contains(char **str_array, const char *item)
{
	unsigned int i = 0;

	if (unlikely(!str_array || !item))
		return false;

	while (str_array[i]) {
		if (!strcmp(str_array[i], item))
			return true;

		i += 1;
	}

	return false;
}

/**
 * l_strv_append:
 * @str_array: a %NULL terminated array of strings or %NULL
 * @str: A string to be appened at the end of @str_array
 *
 * Returns: New %NULL terminated array of strings with @str added
 */
LIB_EXPORT char **l_strv_append(char **str_array, const char *str)
{
	char **ret;
	unsigned int i, len;

	if (unlikely(!str))
		return str_array;

	len = l_strv_length(str_array);
	ret = l_new(char *, len + 2);

	for (i = 0; i < len; i++)
		ret[i] = str_array[i];

	ret[i] = l_strdup(str);

	l_free(str_array);

	return ret;
}

LIB_EXPORT char **l_strv_append_printf(char **str_array,
						const char *format, ...)
{
	va_list args;
	char **ret;

	va_start(args, format);
	ret = l_strv_append_vprintf(str_array, format, args);
	va_end(args);

	return ret;
}

LIB_EXPORT char **l_strv_append_vprintf(char **str_array,
					const char *format, va_list args)
{
	char **ret;
	unsigned int i, len;

	if (unlikely(!format))
		return str_array;

	len = l_strv_length(str_array);
	ret = l_new(char *, len + 2);

	for (i = 0; i < len; i++)
		ret[i] = str_array[i];

	ret[i] = l_strdup_vprintf(format, args);

	l_free(str_array);

	return ret;
}

/**
 * l_strv_copy:
 * @str_array: a %NULL terminated array of strings or %NULL
 *
 * Returns: An independent copy of @str_array.
 */
LIB_EXPORT char **l_strv_copy(char **str_array)
{
	int i, len;
	char **copy;

	if (unlikely(!str_array))
		return NULL;

	for (len = 0; str_array[len]; len++);

	copy = l_malloc(sizeof(char *) * (len + 1));

	for (i = len; i >= 0; i--)
		copy[i] = l_strdup(str_array[i]);

	return copy;
}

/**
 * l_strv_eq:
 * @a: a %NULL terminated array of strings or %NULL
 * @b: another %NULL terminated array of strings or %NULL
 *
 * Returns: Whether @a and @b's contents are identical, including the
 * order, or @a and @b are both %NULL.
 */
LIB_EXPORT bool l_strv_eq(char **a, char **b)
{
	if (!a || !b)
		return a == b;

	for (; *a; a++, b++)
		if (!*b || strcmp(*a, *b))
			return false;

	return !*b;
}
