/*****************************************************************************\
 *  data.c - generic data_t structures
 *****************************************************************************
 *  Copyright (C) SchedMD LLC.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm 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; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm 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 Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#define _ISOC99_SOURCE	/* needed for lrint */

#include <ctype.h>
#include <math.h>

#include "src/common/data.h"
#include "src/common/list.h"
#include "src/common/log.h"
#include "src/common/read_config.h"
#include "src/common/xassert.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"

#define DATA_DEFINE_DICT_PATH_BUFFER_SIZE 1024
#define DATA_MAGIC 0x1992189F
#define DATA_LIST_MAGIC 0x1992F89F
#define DATA_LIST_NODE_MAGIC 0x1921F89F

/* max chars PRId64 could printf(). strlen("-9223372036854775808") = 20 */
#define INT64_CHAR_MAX 20

typedef struct data_list_s data_list_t;
typedef struct data_list_node_s data_list_node_t;

typedef enum {
	TYPE_NONE = 0, /* invalid or unknown type */
	/* only for bounds checks to avoid any overlap with DATA_TYPE_* */
	TYPE_START = 0xFF00,
	TYPE_NULL, /* ECMA-262:4.3.13 NULL type */
	TYPE_LIST, /* ECMA-262:22.1 Array Object (ordered list) */
	TYPE_DICT, /* ECMA-262:23.1 Map Object (dictionary) */
	TYPE_INT_64, /*  64bit signed integer
				This exists as an convenient storage type.
				ECMA does not have an integer primitive.
				ECMA-262:7.1.4 ToInteger() returns approx
				this value with some rounding. */
	TYPE_STRING_PTR, /* ECMA-262:4.3.18 String type */
	TYPE_STRING_INLINE, /* string stored in union directly */
	TYPE_FLOAT, /* ECMA-262:6.1.6 Number type */
	TYPE_BOOL, /* ECMA-262:4.3.15 Boolean type */
	TYPE_MAX /* only for bounds checking */
} type_t;

static const struct {
	data_type_t external_type;
	type_t internal_type;
} type_map[] = {
	{ DATA_TYPE_NULL, TYPE_NULL },
	{ DATA_TYPE_LIST, TYPE_LIST },
	{ DATA_TYPE_DICT, TYPE_DICT },
	{ DATA_TYPE_INT_64, TYPE_INT_64 },
	{ DATA_TYPE_STRING, TYPE_STRING_PTR },
	{ DATA_TYPE_STRING, TYPE_STRING_INLINE },
	{ DATA_TYPE_FLOAT, TYPE_FLOAT },
	{ DATA_TYPE_BOOL, TYPE_BOOL },
};

typedef struct data_list_node_s {
	int magic;
	data_list_node_t *next;

	data_t *data;
	char *key; /* key for dictionary (only) */
} data_list_node_t;

/* Single linked list for list_u and dict_u */
typedef struct data_list_s {
	int magic;
	size_t count;

	data_list_node_t *begin;
	data_list_node_t *end;
} data_list_t;

/*
 * Data is based on the JSON data type and has the same types.
 * Data forms a tree structure.
 * Please avoid direct access of this struct and only use access functions.
 * The nature of this struct may change at any time, only pass around pointers
 * created from data_new().
 */
struct data_s {
	int magic;
	type_t type;

	union { /* append "_u" to every type to avoid reserved words */
		data_list_t *list_u;
		data_list_t *dict_u;
		int64_t int_u;
		char string_inline_u[sizeof(void *)];
		char *string_ptr_u;
		double float_u;
		bool bool_u;
	} data;
};

typedef struct {
	char *path;
	char *at;
	const char *token;
} merge_path_strings_t;

typedef struct {
	const data_t *a;
	const data_t *b;
	bool mask;
} find_dict_match_t;

typedef struct {
	size_t count;
	type_t match;
} convert_args_t;

#define CONVERT_DATA_FOREACH_LIST_DICT_ARGS_MAGIC 0x139414ab

typedef struct {
	int magic; /* CONVERT_DATA_FOREACH_LIST_DICT_ARGS_MAGIC */
	data_t *src;
	int64_t index;
} convert_data_foreach_list_dict_args_t;

static void _check_magic(const data_t *data);
static void _release(data_t *data);
static void _release_data_list_node(data_list_t *dl, data_list_node_t *dn);
static size_t _convert_tree(data_t *data, const type_t match);
static char *_type_to_string(type_t type);

static data_list_t *_data_list_new(void)
{
	data_list_t *dl = xmalloc(sizeof(*dl));
	dl->magic = DATA_LIST_MAGIC;

	log_flag(DATA, "%s: new data-list(0x%"PRIxPTR")[%zu]",
		 __func__, (uintptr_t) dl, dl->count);

	return dl;
}

static void _check_data_list_node_magic(const data_list_node_t *dn)
{
	xassert(dn);
	xassert(dn->magic == DATA_LIST_NODE_MAGIC);
	/* make sure not linking to self */
	xassert(dn->next != dn);
}

static void _check_data_list_magic(const data_list_t *dl)
{
#ifndef NDEBUG
	xassert(dl);
	xassert(dl->magic == DATA_LIST_MAGIC);

	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		data_list_node_t *end = NULL;

		if (dl->begin) {
			/* walk forwards verify */
			int c = 0;
			data_list_node_t *i = dl->begin;

			while (i) {
				c++;
				_check_data_list_node_magic(i);
				end = i;
				i = i->next;
			}

			xassert(c == dl->count);
		}

		xassert(end == dl->end);
	}
#endif /* !NDEBUG */
}

/* verify node is in parent list */
static void _check_data_list_node_parent(const data_list_t *dl,
					 const data_list_node_t *dn)
{
#ifndef NDEBUG
	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		data_list_node_t *i = dl->begin;
		while (i) {
			if (i == dn)
				return;
			i = i->next;
		}

		/* found an orphan? */
		fatal_abort("%s: unexpected orphan node", __func__);
	}
#endif /* !NDEBUG */
}

static void _release_data_list_node(data_list_t *dl, data_list_node_t *dn)
{
	_check_data_list_magic(dl);
	_check_data_list_node_magic(dn);
	_check_data_list_node_parent(dl, dn);
	data_list_node_t *prev;

	log_flag(DATA, "%s: free data-list(0x%"PRIxPTR")[%zu]",
		 __func__, (uintptr_t) dl, dl->count);

	/* walk list to find new previous */
	for (prev = dl->begin; prev && prev->next != dn; ) {
		_check_data_list_node_magic(prev);
		prev = prev->next;
		if (prev)
			_check_data_list_node_magic(prev);
	}

	if (dn == dl->begin) {
		/* at the beginning */
		xassert(!prev);
		dl->begin = dn->next;

		if (dl->end == dn) {
			dl->end = NULL;
			xassert(!dn->next);
		}
	} else if (dn == dl->end) {
		/* at the end */
		xassert(!dn->next);
		xassert(prev);
		dl->end = prev;
		prev->next = NULL;
	} else {
		/* somewhere in middle */
		xassert(prev);
		xassert(prev != dn);
		xassert(prev->next == dn);
		xassert(dl->begin != dn);
		xassert(dl->end != dn);
		prev->next = dn->next;
	}

	dl->count--;
	FREE_NULL_DATA(dn->data);
	xfree(dn->key);

	dn->magic = ~DATA_LIST_NODE_MAGIC;
	xfree(dn);
}

static void _release_data_list(data_list_t *dl)
{
	data_list_node_t *n = dl->begin, *i;
#ifndef NDEBUG
	int count = 0;
	const int init_count = dl->count;
#endif

	_check_data_list_magic(dl);

	if (!n) {
		xassert(!dl->count);
		xassert(!dl->end);
		goto finish;
	}

	xassert(dl->end);

	while((i = n)) {
		n = i->next;
		_release_data_list_node(dl, i);

#ifndef NDEBUG
		count++;
#endif
	}


#ifndef NDEBUG
	xassert(count == init_count);
#endif

finish:
	dl->magic = ~DATA_LIST_MAGIC;
	xfree(dl);
}

/*
 * Create new data list node entry
 * IN d - data type to take ownership of
 * IN key - dictionary key to dup or NULL
 */
static data_list_node_t *_new_data_list_node(data_t *d, const char *key)
{
	data_list_node_t *dn = xmalloc(sizeof(*dn));
	dn->magic = DATA_LIST_NODE_MAGIC;

	_check_magic(d);

	dn->data = d;
	if (key) {
		dn->key = xstrdup(key);

		log_flag(DATA, "%s: new dictionary entry data-list-node(0x%"PRIxPTR")[%s]=%pD",
			 __func__, (uintptr_t) dn, dn->key, dn->data);
	} else {
		log_flag(DATA, "%s: new list entry data-list-node(0x%"PRIxPTR")=%pD",
			 __func__, (uintptr_t) dn, dn->data);
	}

	return dn;
}

static void _data_list_append(data_list_t *dl, data_t *d, const char *key)
{
	data_list_node_t *n = _new_data_list_node(d, key);
	_check_data_list_magic(dl);
	_check_magic(d);

	if (dl->end) {
		xassert(!dl->end->next);
		_check_data_list_node_magic(dl->end);
		_check_data_list_node_magic(dl->begin);

		dl->end->next = n;
		dl->end = n;
	} else {
		xassert(!dl->count);
		dl->end = n;
		dl->begin = n;
	}

	dl->count++;

	if (n->key)
		log_flag(DATA, "%s: append dictionary entry data-list-node(0x%"PRIxPTR")[%s]=%pD",
			 __func__, (uintptr_t) n, n->key, n->data);
	else
		log_flag(DATA, "%s: append list entry data-list-node(0x%"PRIxPTR")=%pD",
			 __func__, (uintptr_t) n, n->data);
}

static void _data_list_prepend(data_list_t *dl, data_t *d, const char *key)
{
	data_list_node_t *n = _new_data_list_node(d, key);
	_check_data_list_magic(dl);
	_check_magic(d);

	if (dl->begin) {
		_check_data_list_node_magic(dl->begin);
		n->next = dl->begin;
		dl->begin = n;
	} else {
		xassert(!dl->count);
		dl->begin = n;
		dl->end = n;
	}

	dl->count++;

	log_flag(DATA, "%s: prepend %pD[%s]->data-list-node(0x%"PRIxPTR")[%s]=%pD",
		 __func__, d, key, (uintptr_t) n, n->key, n->data);
}

extern data_t *data_new(void)
{
	data_t *data = xmalloc(sizeof(*data));
	data->magic = DATA_MAGIC;
	data->type = TYPE_NULL;

	log_flag(DATA, "%s: new %pD", __func__, data);

	return data;
}

static void _check_magic(const data_t *data)
{
	if (!data)
		return;

	xassert(data->magic == DATA_MAGIC);

	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		xassert(data->type > TYPE_START);
		xassert(data->type < TYPE_MAX);

		if (data->type == TYPE_LIST)
			_check_data_list_magic(data->data.list_u);
		if (data->type == TYPE_DICT)
			_check_data_list_magic(data->data.dict_u);
	}
}

static void _release(data_t *data)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_LIST:
		_release_data_list(data->data.list_u);
		break;
	case TYPE_DICT:
		_release_data_list(data->data.dict_u);
		break;
	case TYPE_STRING_PTR:
		xfree(data->data.string_ptr_u);
		break;
	default:
		/* other types don't need to be freed */
		break;
	}

	data->type = TYPE_NONE;
}

extern void data_free(data_t *data)
{
	if (!data)
		return;

	log_flag(DATA, "%s: free %pD", __func__, data);

	_check_magic(data);
	_release(data);

	data->magic = ~DATA_MAGIC;
	data->type = TYPE_NONE;
	xfree(data);
}

extern data_type_t data_get_type(const data_t *data)
{
	if (!data)
		return DATA_TYPE_NONE;

	_check_magic(data);

	for (int i = 0; i < ARRAY_SIZE(type_map); i++)
		if (type_map[i].internal_type == data->type)
			return type_map[i].external_type;

	return DATA_TYPE_NONE;
}

extern data_t *data_set_float(data_t *data, double value)
{
	_check_magic(data);
	if (!data)
		return NULL;

	data->type = TYPE_FLOAT;
	data->data.float_u = value;

	log_flag(DATA, "%s: set %pD=%e", __func__, data, value);

	return data;
}

extern data_t *data_set_null(data_t *data)
{
	_check_magic(data);
	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_NULL;

	log_flag(DATA, "%s: set %pD=null", __func__, data);

	return data;
}

extern data_t *data_set_bool(data_t *data, bool value)
{
	_check_magic(data);
	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_BOOL;
	data->data.bool_u = value;

	log_flag(DATA, "%s: set %pD=%s",
		 __func__, data, (value ? "true" : "false"));

	return data;
}

extern data_t *data_set_int(data_t *data, int64_t value)
{
	_check_magic(data);
	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_INT_64;
	data->data.int_u = value;

	log_flag(DATA, "%s: set %pD=%"PRId64, __func__, data, value);

	return data;
}

static void _set_data_string_ptr(data_t *data, const size_t len,
				  char **value_ptr)
{
	data->type = TYPE_STRING_PTR;
	data->data.string_ptr_u = *value_ptr;
	*value_ptr = NULL;
	log_flag_hex(DATA, data->data.string_ptr_u, len, "%s: set string %pD",
		     __func__, data);
}

static void _set_data_string_inline(data_t *data, const size_t len,
				    const char *value)
{
	memmove(data->data.string_inline_u, value, len + 1);
	data->type = TYPE_STRING_INLINE;
	log_flag_hex(DATA, data->data.string_inline_u, len,
		     "%s: set inline string %pD", __func__, data);
}

extern data_t *data_set_string(data_t *data, const char *value)
{
	int len;

	_check_magic(data);

	if (!data)
		return NULL;
	_release(data);

	if (!value) {
		data->type = TYPE_NULL;

		log_flag(DATA, "%s: set %pD=null", __func__, data);
		return data;
	}

	if ((len = strlen(value)) < sizeof(data->data.string_inline_u)) {
		_set_data_string_inline(data, len, value);
	} else {
		char *dval = xstrdup(value);
		_set_data_string_ptr(data, len, &dval);
	}

	return data;
}

extern data_t *_data_set_string_own(data_t *data, char **value_ptr)
{
	char *value;
	int len;
	_check_magic(data);

	if (!data) {
		xfree(*value_ptr);
		return NULL;
	}

	_release(data);

	value = *value_ptr;
	*value_ptr = NULL;

	if (!value) {
		data->type = TYPE_NULL;

		log_flag(DATA, "%s: set %pD=null", __func__, data);
		return data;
	}

#ifndef NDEBUG
	if (slurm_conf.debug_flags & DEBUG_FLAG_DATA) {
		char *old_value = value;

		/* check that the string was xmalloc()ed and actually has contents */
		xassert(xsize(value) > 0);
		/*
		 * catch use after free by the caller by using the existing xfree()
		 * functionality
		 */
		value = xstrdup(value);
		/* releasing original string instead of NULLing original pointer */
		xfree(old_value);
	}
#endif

	if ((len = strlen(value)) < sizeof(data->data.string_inline_u)) {
		_set_data_string_inline(data, len, value);
		/* we don't need to keep this string alloc */
		xfree(value);
	} else {
		_set_data_string_ptr(data, len, &value);
	}

	xassert(!value);
	return data;
}

extern data_t *data_set_dict(data_t *data)
{
	_check_magic(data);

	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_DICT;
	data->data.dict_u = _data_list_new();

	log_flag(DATA, "%s: set %pD to dictionary", __func__, data);

	return data;
}

extern data_t *data_set_list(data_t *data)
{
	_check_magic(data);

	if (!data)
		return NULL;
	_release(data);

	data->type = TYPE_LIST;
	data->data.list_u = _data_list_new();

	log_flag(DATA, "%s: set %pD to list", __func__, data);

	return data;
}

extern data_t *data_list_append(data_t *data)
{
	data_t *ndata = NULL;
	_check_magic(data);

	xassert(data && (data->type == TYPE_LIST));
	if (!data || data->type != TYPE_LIST)
		return NULL;

	ndata = data_new();
	_data_list_append(data->data.list_u, ndata, NULL);

	log_flag(DATA, "%s: appended %pD[%zu]=%pD",
		 __func__, data, data->data.list_u->count, ndata);

	return ndata;
}

extern data_t *data_list_prepend(data_t *data)
{
	data_t *ndata = NULL;
	_check_magic(data);

	if (!data || data->type != TYPE_LIST)
		return NULL;

	ndata = data_new();
	_data_list_prepend(data->data.list_u, ndata, NULL);

	log_flag(DATA, "%s: prepended %pD[%zu]=%pD",
		 __func__, data, data->data.list_u->count, ndata);

	return ndata;
}

extern data_t *data_list_dequeue(data_t *data)
{
	data_list_node_t *n;
	data_t *ret = NULL;
	_check_magic(data);

	if (!data || data->type != TYPE_LIST)
		return NULL;

	if (!(n = data->data.list_u->begin))
		return NULL;

	_check_data_list_node_magic(n);

	/* extract out data for caller */
	SWAP(ret, n->data);

	/* remove node from list */
	_release_data_list_node(data->data.list_u, n);

	log_flag(DATA, "%s: dequeued %pD[%zu]=%pD",
		 __func__, data, data->data.list_u->count, ret);

	return ret;
}

static data_for_each_cmd_t _data_list_join(const data_t *src, void *arg)
{
	data_t *dst = (data_t *) arg;
	data_t *dst_entry;
	_check_magic(src);
	_check_magic(dst);
	xassert(dst->type == TYPE_LIST);

	log_flag(DATA, "%s: list join data %pD to %pD", __func__, src, dst);

	dst_entry = data_list_append(dst);
	data_copy(dst_entry, src);

	log_flag(DATA, "%s: list join %pD to %pD[%zu]=%pD",
		 __func__, src, dst, dst->data.list_u->count, dst_entry);

	 return DATA_FOR_EACH_CONT;
}

extern data_t *data_list_join(const data_t **data, bool flatten_lists)
{
	data_t *dst = data_set_list(data_new());

	for (size_t i = 0; data[i]; i++) {
		log_flag(DATA, "%s: %s list join %pD to %pD[%zu]",
			 __func__, (flatten_lists ? "flattened" : ""),
			 data[i], dst, dst->data.list_u->count);

		if (flatten_lists && (data[i]->type == TYPE_LIST))
			(void) data_list_for_each_const(data[i],
							_data_list_join, dst);
		else /* simple join */
			_data_list_join(data[i], dst);
	}

	return dst;
}

extern const data_t *data_key_get_const(const data_t *data, const char *key)
{
	const data_list_node_t *i;

	_check_magic(data);
	if (!data)
		return NULL;

	xassert(data->type == TYPE_DICT);
	if (!key || data->type != TYPE_DICT)
		return NULL;

	/* don't bother searching empty dictionary */
	if (!data->data.dict_u->count)
		return NULL;

	_check_data_list_magic(data->data.dict_u);
	i = data->data.dict_u->begin;
	while (i) {
		_check_data_list_node_magic(i);

		if (!xstrcmp(key, i->key))
			break;

		i = i->next;
	}

	if (i)
		return i->data;
	else
		return NULL;
}

static bool _match_string(const char *key, data_t *data, void *needle_ptr)
{
	const char *needle = needle_ptr;
	return !xstrcmp(key, needle);
}

extern data_t *data_key_get(data_t *data, const char *key)
{
	return data_dict_find_first(data, _match_string, (void *) key);
}

extern data_t *data_key_get_int(data_t *data, int64_t key)
{
	char key_str[INT64_CHAR_MAX + 1];

	(void) snprintf(key_str, sizeof(key_str), "%"PRId64, key);

	return data_key_get(data, key_str);
}

extern data_t *data_list_find_first(
	data_t *data,
	bool (*match)(const data_t *data, void *needle),
	void *needle)
{
	data_list_node_t *i;

	_check_magic(data);
	if (!data)
		return NULL;

	xassert(data->type == TYPE_LIST);
	if (data->type != TYPE_LIST)
		return NULL;

	/* don't bother searching empty list */
	if (!data->data.list_u->count)
		return NULL;

	_check_data_list_magic(data->data.list_u);
	i = data->data.list_u->begin;
	while (i) {
		_check_data_list_node_magic(i);

		if (match(i->data, needle))
			break;

		i = i->next;
	}

	if (i)
		return i->data;
	else
		return NULL;
}

extern data_t *data_dict_find_first(
	data_t *data,
	bool (*match)(const char *key, data_t *data, void *needle),
	void *needle)
{
	data_list_node_t *i;

	_check_magic(data);
	if (!data)
		return NULL;

	xassert(data->type == TYPE_DICT);
	if (data->type != TYPE_DICT)
		return NULL;

	/* don't bother searching empty dictionary */
	if (!data->data.dict_u->count)
		return NULL;

	_check_data_list_magic(data->data.dict_u);
	i = data->data.dict_u->begin;
	while (i) {
		_check_data_list_node_magic(i);

		if (match(i->key, i->data, needle))
			break;

		i = i->next;
	}

	if (i)
		return i->data;
	else
		return NULL;
}

extern data_t *data_key_set(data_t *data, const char *key)
{
	data_t *d;

	_check_magic(data);

	if (!data)
		return NULL;

	xassert(data->type == TYPE_DICT);
	if (!key || (data->type != TYPE_DICT))
		return NULL;

	if ((d = data_key_get(data, key))) {
		log_flag(DATA, "%s: overwrite existing key in %pD[%s]=%pD",
			 __func__, data, key, d);
		return d;
	}

	d = data_new();
	_data_list_append(data->data.dict_u, d, key);

	log_flag(DATA, "%s: populate new key in %pD[%s]=%pD",
		 __func__, data, key, d);

	return d;
}

extern data_t *data_key_set_int(data_t *data, int64_t key)
{
	char key_str[INT64_CHAR_MAX + 1];

	(void) snprintf(key_str, sizeof(key_str), "%"PRId64, key);

	return data_key_set(data, key_str);
}

extern bool data_key_unset(data_t *data, const char *key)
{
	data_list_node_t *i;

	_check_magic(data);
	if (!data)
		return false;

	xassert(data->type == TYPE_DICT);
	if (!key || data->type != TYPE_DICT)
		return NULL;

	_check_data_list_magic(data->data.dict_u);
	i = data->data.dict_u->begin;
	while (i) {
		_check_data_list_node_magic(i);

		if (!xstrcmp(key, i->key))
			break;

		i = i->next;
	}

	if (!i) {
		log_flag(DATA, "%s: remove non-existent key in %pD[%s]",
			 __func__, data, key);
		return false;
	}

	log_flag(DATA, "%s: remove existing key in %pD[%s]=data-list-node(0x%"PRIxPTR")[%s]=%pD",
		 __func__, data, key, (uintptr_t) i, i->key, i->data);

	_release_data_list_node(data->data.dict_u, i);

	return true;
}

extern double data_get_float(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return NAN;

	xassert(data->type == TYPE_FLOAT);
	return data->data.float_u;
}

extern bool data_get_bool(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return false;

	xassert(data->type == TYPE_BOOL);
	return data->data.bool_u;
}

extern int64_t data_get_int(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return 0;

	if (data->type == TYPE_NULL)
		return 0;

	xassert(data->type == TYPE_INT_64);
	return data->data.int_u;
}

extern const char *data_get_string(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return NULL;

	xassert((data->type == TYPE_STRING_PTR) ||
		(data->type == TYPE_STRING_INLINE) ||
		(data->type == TYPE_NULL));

	if (data->type == TYPE_STRING_PTR) {
		return data->data.string_ptr_u;
	} else if (data->type == TYPE_STRING_INLINE) {
		return data->data.string_inline_u;
	} else {
		return NULL;
	}
}

extern int data_get_string_converted(const data_t *d, char **buffer)
{
	_check_magic(d);
	char *_buffer = NULL;
	bool cloned;

	if (!d || !buffer)
		return ESLURM_DATA_PTR_NULL;

	if ((d->type != TYPE_STRING_PTR) && (d->type != TYPE_STRING_INLINE)) {
		/* copy the data and then convert it to a string type */
		data_t *dclone = data_new();
		data_copy(dclone, d);
		if (data_convert_type(dclone, DATA_TYPE_STRING) ==
		    DATA_TYPE_STRING)
			_buffer = xstrdup(data_get_string(dclone));
		FREE_NULL_DATA(dclone);
		cloned = true;
	} else {
		_buffer = xstrdup(data_get_string(d));
		if (!_buffer)
			_buffer = xstrdup("");
		cloned = false;
	}

	if (_buffer) {
		*buffer = _buffer;

		log_flag_hex(DATA, _buffer, strlen(_buffer),
			     "%s: string %sat %pD=string@0x%"PRIxPTR"[%zu]",
			     __func__, (cloned ? "conversion and cloned " : ""),
			     d, (uintptr_t) _buffer, strlen(_buffer));

		return SLURM_SUCCESS;
	}

	log_flag(DATA, "%s: %pD string conversion failed", __func__, d);

	return ESLURM_DATA_CONV_FAILED;
}

extern int data_copy_bool_converted(const data_t *d, bool *buffer)
{
	_check_magic(d);
	int rc = ESLURM_DATA_CONV_FAILED;

	if (!d || !buffer)
		return ESLURM_DATA_PTR_NULL;

	if (d->type != TYPE_BOOL) {
		data_t *dclone = data_new();
		data_copy(dclone, d);
		if (data_convert_type(dclone, DATA_TYPE_BOOL) ==
		    DATA_TYPE_BOOL) {
			*buffer = data_get_bool(dclone);
			rc = SLURM_SUCCESS;
		}
		FREE_NULL_DATA(dclone);

		log_flag(DATA, "%s: converted %pD=%s",
			 __func__, d, (*buffer ? "true" : "false"));
		return rc;
	}

	*buffer = data_get_bool(d);
	return SLURM_SUCCESS;
}

extern int data_get_bool_converted(data_t *d, bool *buffer)
{
	int rc;
	_check_magic(d);

	if (!d || !buffer)
		return ESLURM_DATA_PTR_NULL;

	/* assign value if converted successfully */
	rc = data_copy_bool_converted(d, buffer);
	if (!rc)
		data_set_bool(d, *buffer);

	return rc;
}

extern int data_get_int_converted(const data_t *d, int64_t *buffer)
{
	_check_magic(d);
	int rc = SLURM_SUCCESS;

	if (!d || !buffer)
		return ESLURM_DATA_PTR_NULL;

	if (d->type != TYPE_INT_64) {
		data_t *dclone = data_new();
		data_copy(dclone, d);
		if (data_convert_type(dclone, DATA_TYPE_INT_64) ==
		    DATA_TYPE_INT_64)
			*buffer = data_get_int(dclone);
		else
			rc = ESLURM_DATA_CONV_FAILED;
		FREE_NULL_DATA(dclone);
	} else {
		*buffer = data_get_int(d);
	}

	log_flag(DATA, "%s: converted %pD=%"PRId64, __func__, d, *buffer);

	return rc;
}

extern size_t data_get_dict_length(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return 0;

	xassert(data->type == TYPE_DICT);
	return data->data.dict_u->count;
}

extern size_t data_get_list_length(const data_t *data)
{
	_check_magic(data);

	if (!data)
		return 0;

	xassert(data->type == TYPE_LIST);
	return data->data.list_u->count;
}

extern data_t *data_get_list_last(data_t *data)
{
	data_list_node_t *i;
	_check_magic(data);

	if (!data)
		return NULL;

	xassert(data->type == TYPE_LIST);
	if (data->type != TYPE_LIST)
		return NULL;

	if (!data->data.list_u->count)
		return NULL;

	i = data->data.list_u->begin;
	_check_data_list_magic(data->data.list_u);
	while (i) {
		_check_data_list_node_magic(i);
		xassert(!i->key);

		if (!i->next) {
			log_flag(DATA, "%s: %pD[%s]=%pD",
				 __func__, data, i->key, i->data);
			return i->data;
		}

		i = i->next;
	}

	fatal_abort("%s: malformed data list", __func__);
}

extern int data_list_split_str(data_t *dst, const char *src, const char *token)
{
	char *save_ptr = NULL;
	char *tok = NULL;
	char *str = xstrdup(src);

	if (dst->type == TYPE_NULL)
		data_set_list(dst);

	xassert(dst->type == TYPE_LIST);
	if (dst->type != TYPE_LIST)
		return SLURM_ERROR;

	if (str && !str[0])
		xfree(str);

	if (!str)
		return SLURM_SUCCESS;

	tok = strtok_r(str, "/", &save_ptr);
	while (tok) {
		data_t *e = data_list_append(dst);
		xstrtrim(tok);

		data_set_string(e, tok);

		log_flag_hex(DATA, tok, strlen(tok),
			     "%s: split string from 0x%"PRIxPTR" to %pD[%zu]=%pD",
			     __func__, src, dst, dst->data.list_u->count, e);

		tok = strtok_r(NULL, "/", &save_ptr);
	}
	xfree(str);

	return SLURM_SUCCESS;
}

static data_for_each_cmd_t _foreach_join_str(const data_t *data, void *arg)
{
	char *b = NULL;
	merge_path_strings_t *args = arg;

	if (!data_get_string_converted(data, &b))
		xstrfmtcatat(args->path, &args->at, "%s%s%s",
			     (!args->path ? args->token : ""),
			     (args->at ? args->token : ""), b);

	xfree(b);

	return DATA_FOR_EACH_CONT;
}

extern int data_list_join_str(char **dst, const data_t *src, const char *token)
{
	merge_path_strings_t args = {
		.token = token,
	};

	xassert(!*dst);
	xassert(src->type == TYPE_LIST);

	if (data_list_for_each_const(src, _foreach_join_str, &args) < 0) {
		xfree(args.path);
		return SLURM_ERROR;
	}

	*dst = args.path;

	log_flag_hex(DATA, *dst, strlen(*dst),
		     "%s: %pD string joined with token %s",
		     __func__, src, token);

	return SLURM_SUCCESS;
}

extern int data_list_for_each_const(const data_t *d, DataListForFConst f, void *arg)
{
	int count = 0;
	const data_list_node_t *i;

	_check_magic(d);

	if (!d || (d->type != TYPE_LIST)) {
		error("%s: for each attempted on non-list object (0x%"PRIXPTR")",
		      __func__, (uintptr_t) d);
		return -1;
	}

	i = d->data.list_u->begin;
	_check_data_list_magic(d->data.list_u);
	while (i) {
		_check_data_list_node_magic(i);

		xassert(!i->key);
		data_for_each_cmd_t cmd = f(i->data, arg);
		count++;

		xassert(cmd > DATA_FOR_EACH_INVALID);
		xassert(cmd < DATA_FOR_EACH_MAX);

		switch (cmd) {
		case DATA_FOR_EACH_CONT:
			break;
		case DATA_FOR_EACH_DELETE:
			fatal_abort("%s: delete attempted against const",
				    __func__);
			break;
		case DATA_FOR_EACH_FAIL:
			count *= -1;
			/* fall through */
		case DATA_FOR_EACH_STOP:
			i = NULL;
			break;
		default:
			fatal_abort("%s: invalid cmd", __func__);
		}

		if (i)
			i = i->next;
	}

	return count;
}

extern int data_list_for_each(data_t *d, DataListForF f, void *arg)
{
	int count = 0;
	data_list_node_t *i;

	_check_magic(d);

	if (!d || (d->type != TYPE_LIST)) {
		error("%s: for each attempted on non-list %pD", __func__, d);
		return -1;
	}

	i = d->data.list_u->begin;
	_check_data_list_magic(d->data.list_u);
	while (i) {
		_check_data_list_node_magic(i);

		xassert(!i->key);
		data_for_each_cmd_t cmd = f(i->data, arg);
		count++;

		xassert(cmd > DATA_FOR_EACH_INVALID);
		xassert(cmd < DATA_FOR_EACH_MAX);

		switch (cmd) {
		case DATA_FOR_EACH_CONT:
			if (i)
				i = i->next;
			break;
		case DATA_FOR_EACH_DELETE:
		{
			data_list_node_t *idel = i;
			i = i->next;
			_release_data_list_node(d->data.list_u, idel);
			_check_data_list_magic(d->data.list_u);
			break;
		}
		case DATA_FOR_EACH_FAIL:
			count *= -1;
			/* fall through */
		case DATA_FOR_EACH_STOP:
			i = NULL;
			break;
		default:
			fatal_abort("%s: invalid cmd", __func__);
		}
	}

	return count;
}

extern int data_dict_for_each_const(const data_t *d, DataDictForFConst f, void *arg)
{
	int count = 0;
	const data_list_node_t *i;

	if (!d)
		return 0;

	_check_magic(d);

	if (data_get_type(d) != DATA_TYPE_DICT) {
		error("%s: for each attempted on non-dict %pD", __func__, d);
		return -1;
	}

	i = d->data.dict_u->begin;
	_check_data_list_magic(d->data.dict_u);
	while (i) {
		data_for_each_cmd_t cmd;

		_check_data_list_node_magic(i);

		cmd = f(i->key, i->data, arg);
		count++;

		xassert(cmd > DATA_FOR_EACH_INVALID);
		xassert(cmd < DATA_FOR_EACH_MAX);

		switch (cmd) {
		case DATA_FOR_EACH_CONT:
			break;
		case DATA_FOR_EACH_DELETE:
			fatal_abort("%s: delete attempted against const",
				    __func__);
			break;
		case DATA_FOR_EACH_FAIL:
			count *= -1;
			/* fall through */
		case DATA_FOR_EACH_STOP:
			i = NULL;
			break;
		default:
			fatal_abort("%s: invalid cmd", __func__);
		}

		if (i)
			i = i->next;
	}

	return count;
}

extern int data_dict_for_each(data_t *d, DataDictForF f, void *arg)
{
	int count = 0;
	data_list_node_t *i;

	if (!d)
		return 0;

	_check_magic(d);

	if (data_get_type(d) != DATA_TYPE_DICT) {
		error("%s: for each attempted on non-dict %pD", __func__, d);
		return -1;
	}

	i = d->data.dict_u->begin;
	_check_data_list_magic(d->data.dict_u);
	while (i) {
		_check_data_list_node_magic(i);

		data_for_each_cmd_t cmd = f(i->key, i->data, arg);
		count++;

		xassert(cmd > DATA_FOR_EACH_INVALID);
		xassert(cmd < DATA_FOR_EACH_MAX);

		switch (cmd) {
		case DATA_FOR_EACH_CONT:
			if (i)
				i = i->next;
			break;
		case DATA_FOR_EACH_DELETE:
		{
			data_list_node_t *idel = i;
			i = i->next;
			_release_data_list_node(d->data.list_u, idel);
			_check_data_list_magic(d->data.list_u);
			break;
		}
		case DATA_FOR_EACH_FAIL:
			count *= -1;
			/* fall through */
		case DATA_FOR_EACH_STOP:
			i = NULL;
			break;
		default:
			fatal_abort("%s: invalid cmd", __func__);
		}
	}

	return count;
}

static void _convert_data_string(data_t *data)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		break;
	case TYPE_BOOL:
		data_set_string(data, (data->data.bool_u ? "true" : "false"));
		break;
	case TYPE_NULL:
		data_set_string(data, "");
		break;
	case TYPE_FLOAT:
	{
		char *str = xstrdup_printf("%lf", data->data.float_u);
		data_set_string_own(data, str);
		break;
	}
	case TYPE_INT_64:
	{
		char *str = xstrdup_printf("%"PRId64, data->data.int_u);
		data_set_string_own(data, str);
		break;
	}
	default:
		break;
	}
}

static void _convert_data_force_bool(data_t *data)
{
	_check_magic(data);

	/* attempt to detect the type first */
	(void) data_convert_type(data, DATA_TYPE_NONE);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		/* non-empty string but not recognized format */
		data_set_bool(data, true);
		break;
	case TYPE_BOOL:
		break;
	case TYPE_NULL:
		data_set_bool(data, false);
		break;
	case TYPE_FLOAT:
		data_set_bool(data, data->data.float_u != 0);
		break;
	case TYPE_INT_64:
		data_set_bool(data, data->data.int_u != 0);
		break;
	default:
		break;
	}
}

static int _convert_data_null(data_t *data)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
	{
		const char *str = data_get_string(data);

		if (!str[0])
			goto convert;

		if (str[0] == '~')
			goto convert;

		if (!xstrcasecmp(str, "null"))
			goto convert;

		goto fail;
	}
	case TYPE_NULL:
		return SLURM_SUCCESS;
	default:
		return ESLURM_DATA_CONV_FAILED;
	}
fail:
	return ESLURM_DATA_CONV_FAILED;
convert:
	log_flag_hex(DATA, data_get_string(data), strlen(data_get_string(data)),
		     "%s: converted %pD->null", __func__, data);
	data_set_null(data);
	return SLURM_SUCCESS;
}

static int _convert_data_bool(data_t *data)
{
	const char *str = NULL;

	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
	{
		str = data_get_string(data);

		if (tolower(str[0]) == 'y') {
			if (!str[1] || ((tolower(str[1]) == 'e') &&
					(tolower(str[2]) == 's') &&
					(str[3] == '\0'))) {
				data_set_bool(data, true);
				goto converted;
			}
			goto fail;
		} else if (tolower(str[0]) == 't') {
			if (!str[1] || ((tolower(str[1]) == 'r') &&
					(tolower(str[2]) == 'u') &&
					(tolower(str[3]) == 'e') &&
					(str[4] == '\0'))) {
				data_set_bool(data, true);
				goto converted;
			}
			goto fail;
		} else if ((tolower(str[0]) == 'o') &&
			   (tolower(str[1]) == 'n') &&
			   (str[2] == '\0')) {
			data_set_bool(data, true);
			goto converted;
		} else if (tolower(str[0]) == 'n') {
			if (!str[1] || ((tolower(str[1]) == 'o') &&
					(str[2] == '\0'))) {
				data_set_bool(data, false);
				goto converted;
			}
			goto fail;
		} else if (tolower(str[0]) == 'f') {
			if (!str[1] || ((tolower(str[1]) == 'a') &&
					(tolower(str[2]) == 'l') &&
					(tolower(str[3]) == 's') &&
					(tolower(str[4]) == 'e') &&
					(str[5] == '\0'))) {
				data_set_bool(data, false);
				goto converted;
			}
			goto fail;
		} else if ((tolower(str[0]) == 'o') &&
			   (tolower(str[1]) == 'f') &&
			   (tolower(str[2]) == 'f') &&
			   (str[3] == '\0')) {
			data_set_bool(data, false);
			goto converted;
		}

		goto fail;
	}
	case TYPE_BOOL:
		return SLURM_SUCCESS;
	default:
		goto fail;
	}

converted:
	log_flag_hex(DATA, str, strlen(str),
		     "%s: converted %pD->%s",
		 __func__, data, (data_get_bool(data) ? "true" : "false"));
	return SLURM_SUCCESS;

fail:
	if (str)
		log_flag_hex(DATA, str, strlen(str),
			     "%s: converting %pD to bool failed",
			     __func__, data);
	else
		log_flag(DATA, "%s: converting %pD to bool failed",
			 __func__, data);
	return ESLURM_DATA_CONV_FAILED;
}

static int _convert_data_int(data_t *data, bool force)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
	{
		int64_t x;
		char end;
		const char *str = data_get_string(data);

		if (!str[0]) {
			log_flag_hex(DATA, str, strlen(str),
				     "%s: convert empty string %pD to integer failed",
				     __func__, data);
			return ESLURM_DATA_CONV_FAILED;
		}

		if ((str[0] == '0') && (tolower(str[1]) == 'x')) {
			if (sscanf(str, "%"SCNx64"%c", &x, &end) == 1) {
				log_flag_hex(DATA, str, strlen(str),
					     "%s: converted hex number %pD->%"PRId64,
					 __func__, data, x);
				data_set_int(data, x);
				return SLURM_SUCCESS;
			}

			log_flag_hex(DATA, str, strlen(str),
				     "%s: conversion of hex string %pD to integer failed",
				     __func__, data);
			return ESLURM_DATA_CONV_FAILED;
		}

		if (!force) {
			for (const char *p = str; *p; p++) {
				if ((*p < '0') || (*p > '9')) {
					log_flag_hex(DATA, str, strlen(str),
						     "%s: rejecting non-numeric conversion of %pD to integer failed",
						     __func__, data);
					return ESLURM_DATA_CONV_FAILED;
				}
			}
		}

		if (sscanf(str, "%"SCNd64"%c", &x, &end) == 1) {
			log_flag_hex(DATA, str, strlen(str),
				     "%s: converted %pD->%"PRId64,
				     __func__, data, x);
			data_set_int(data, x);
			return SLURM_SUCCESS;
		} else {
			log_flag_hex(DATA, str, strlen(str),
				     "%s: conversion of %pD to integer failed",
				     __func__, data);
			return ESLURM_DATA_CONV_FAILED;
		}
	}
	case TYPE_FLOAT:
		if (force) {
			data_set_int(data, lrint(data_get_float(data)));
			return SLURM_SUCCESS;
		}
		return ESLURM_DATA_CONV_FAILED;
	case TYPE_INT_64:
		return SLURM_SUCCESS;
	case TYPE_NULL:
		if (force) {
			/*
			 * Conversion from NULL to integer is a loss of
			 * information as NULL implies value is not set where as
			 * integer 0 could just mean there is a a value zero as
			 * opposed to there be no value set. This conversion is
			 * only done when force is true as such.
			 */
			data_set_int(data, 0);
			return SLURM_SUCCESS;
		}
	default:
		return ESLURM_DATA_CONV_FAILED;
	}
}

static int _convert_data_float_from_string(data_t *data)
{
	const char *str = data_get_string(data);
	int i = 0;
	bool negative = false;

	xassert(str);

	if (str[i] == '+') {
		i++;
	} else if (str[i] == '-') {
		i++;
		negative = true;
	}

	if ((tolower(str[i]) == 'i')) {
		i++;

		if (!xstrcasecmp(&str[i], "nf") ||
		    !xstrcasecmp(&str[i], "nfinity")) {
			if (negative)
				data_set_float(data, -INFINITY);
			else
				data_set_float(data, INFINITY);

			goto converted;
		}

		goto fail;
	}

	if ((tolower(str[i]) == 'n')) {
		i++;

		if (!xstrcasecmp(&str[i], "an")) {
			if (negative)
				data_set_float(data, -NAN);
			else
				data_set_float(data, NAN);

			goto converted;
		}

		goto fail;
	}

	if ((str[i] >= '0') && (str[i] <= '9')) {
		char end;
		double x;

		if (sscanf(&str[i], "%lf%c", &x, &end) == 1) {
			if (negative)
				x *= -1;
			data_set_float(data, x);
			goto converted;
		}
	}

	goto fail;

converted:
	log_flag(DATA, "%s: converted %pD to float: %s->%lf",
		 __func__, data, str, data_get_float(data));
	return SLURM_SUCCESS;

fail:
	log_flag_hex(DATA, str, strlen(str),
		     "%s: convert %pD to double float failed", __func__, data);
	return ESLURM_DATA_CONV_FAILED;
}

static int _convert_data_float(data_t *data)
{
	_check_magic(data);

	switch (data->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		return _convert_data_float_from_string(data);
	case TYPE_INT_64:
		if (data_get_int(data) == INFINITE64)
			data_set_float(data, HUGE_VAL);
		else if (data_get_int(data) == NO_VAL64)
			data_set_float(data, NAN);
		else /* attempt normal fp conversion */
			data_set_float(data, data_get_int(data));
		return SLURM_SUCCESS;
	case TYPE_FLOAT:
		return SLURM_SUCCESS;
	default:
		return ESLURM_DATA_CONV_FAILED;
	}

	return ESLURM_DATA_CONV_FAILED;
}

static data_for_each_cmd_t _convert_data_foreach_dict_list(const char *key,
							   data_t *data,
							   void *arg)
{
	data_t *src = arg;

	_check_magic(src);

	(void) data_move(data_list_append(src), data);

	return DATA_FOR_EACH_CONT;
}

static int _convert_data_dict_list(data_t *src)
{
	int rc = SLURM_SUCCESS;
	data_t *dict = data_new();

	(void) data_move(dict, src);
	(void) data_set_list(src);

	if (data_dict_for_each(dict, _convert_data_foreach_dict_list, src) < 0)
		rc = ESLURM_DATA_CONV_FAILED;

	FREE_NULL_DATA(dict);
	return rc;
}

static data_for_each_cmd_t _convert_data_foreach_list_dict(data_t *data,
							   void *arg)
{
	convert_data_foreach_list_dict_args_t *args = arg;
	xassert(args->magic == CONVERT_DATA_FOREACH_LIST_DICT_ARGS_MAGIC);

	(void) data_move(data_key_set_int(args->src, args->index), data);
	args->index++;

	return DATA_FOR_EACH_CONT;
}

static int _convert_data_list_dict(data_t *src)
{
	int rc = SLURM_SUCCESS;
	convert_data_foreach_list_dict_args_t args = {
		.magic = CONVERT_DATA_FOREACH_LIST_DICT_ARGS_MAGIC,
		.src = src,
	};
	data_t *list = data_new();

	(void) data_move(list, src);
	(void) data_set_dict(src);

	if (data_list_for_each(list, _convert_data_foreach_list_dict, &args) <
	    0)
		rc = ESLURM_DATA_CONV_FAILED;

	FREE_NULL_DATA(list);
	return rc;
}

extern data_type_t data_convert_type(data_t *data, data_type_t match)
{
	_check_magic(data);

	if (!data)
		return DATA_TYPE_NONE;

	switch (match) {
	case DATA_TYPE_STRING:
		_convert_data_string(data);
		break;
	case DATA_TYPE_BOOL:
		_convert_data_force_bool(data);
		break;
	case DATA_TYPE_INT_64:
		(void) _convert_data_int(data, true);
		break;
	case DATA_TYPE_FLOAT:
		(void) _convert_data_float(data);
		break;
	case DATA_TYPE_NULL:
		(void) _convert_data_null(data);
		break;
	case DATA_TYPE_NONE:
		/* If a conversion succeeds skip calling the others */
		if (!_convert_data_null(data) ||
		    !_convert_data_int(data, false) ||
		    !_convert_data_float(data) ||
		    !_convert_data_int(data, true) || !_convert_data_bool(data))
			; /* blank on purpose */

		break;
	case DATA_TYPE_DICT:
		if (data->type == TYPE_DICT)
			return DATA_TYPE_DICT;
		else if ((data->type == TYPE_LIST) &&
			 !_convert_data_list_dict(data))
			return DATA_TYPE_DICT;

		/* data_parser should be used for this conversion instead. */
		break;
	case DATA_TYPE_LIST:
		if (data->type == TYPE_LIST)
			return DATA_TYPE_LIST;
		else if ((data->type == TYPE_DICT) &&
			 !_convert_data_dict_list(data))
			return DATA_TYPE_LIST;

		/* data_parser should be used for this conversion instead. */
		break;
	case DATA_TYPE_MAX:
		fatal_abort("%s: unexpected data type", __func__);
	default:
		fatal_abort("%s: invalid conversion requested", __func__);
	}

	return data_get_type(data);
}

static data_for_each_cmd_t _convert_list_entry(data_t *data, void *arg)
{
	convert_args_t *args = arg;

	args->count += _convert_tree(data, args->match);

	return DATA_FOR_EACH_CONT;
}

static data_for_each_cmd_t _convert_dict_entry(const char *key, data_t *data,
					       void *arg)
{
	convert_args_t *args = arg;

	args->count += _convert_tree(data, args->match);

	return DATA_FOR_EACH_CONT;
}

static size_t _convert_tree(data_t *data, const type_t match)
{
	convert_args_t args = {
		.match = match,
	};
	_check_magic(data);

	if (!data)
		return 0;

	switch (data->type) {
	case TYPE_DICT:
		(void)data_dict_for_each(data, _convert_dict_entry, &args);
		break;
	case TYPE_LIST:
		(void)data_list_for_each(data, _convert_list_entry, &args);
		break;
	default:
		if (match == (int) data_convert_type(data, (int) match))
			args.count++;
		break;
	}

	return args.count;
}

extern size_t data_convert_tree(data_t *data, const data_type_t match)
{
	return _convert_tree(data, (int) match);
}

static data_for_each_cmd_t _find_dict_match(const char *key, const data_t *a,
					    void *arg)
{
	bool rc;
	find_dict_match_t *p = arg;
	const data_t *b = data_key_get_const(p->b, key);

	rc = data_check_match(a, b, p->mask);

	log_flag(DATA, "dictionary compare: %s(0x%"PRIXPTR")=%s(0x%"PRIXPTR") %s %s(0x%"PRIXPTR")=%s(0x%"PRIXPTR")",
		 key, (uintptr_t) p->a, _type_to_string(a->type), (uintptr_t) a,
		 (rc ? "\u2261" : "\u2260"), key, (uintptr_t) p->b,
		 (b ? _type_to_string(b->type) : _type_to_string(TYPE_NONE)),
		 (uintptr_t) b);

	return rc ? DATA_FOR_EACH_CONT : DATA_FOR_EACH_FAIL;
}

static bool _data_match_dict(const data_t *a, const data_t *b, bool mask)
{
	find_dict_match_t p = {
		.mask = mask,
		.a = a,
		.b = b,
	};

	if (!a || (a->type != TYPE_DICT))
		return false;

	if (!b || (b->type != TYPE_DICT))
		return false;

	_check_magic(a);
	_check_magic(b);

	if (a->data.dict_u->count != b->data.dict_u->count)
		return false;

	/* match by key and not order with dictionary */
	return (data_dict_for_each_const(a, _find_dict_match, &p) >= 0);
}

static bool _data_match_lists(const data_t *a, const data_t *b, bool mask)
{
	bool fail = false;
	const data_list_node_t *ptr_a;
	const data_list_node_t *ptr_b;

	if (!a || (a->type != TYPE_LIST))
		return false;
	if (!b || (b->type != TYPE_LIST))
		return false;

	_check_magic(a);
	_check_magic(b);

	if (a->data.list_u->count != b->data.list_u->count)
		return false;

	ptr_a = a->data.list_u->begin;
	ptr_b = b->data.list_u->begin;

	while (ptr_a && !fail) {
		_check_data_list_node_magic(ptr_a);

		if (!ptr_b && mask)
			/* ignore a if b is NULL when masking */
			continue;

		_check_data_list_node_magic(ptr_b);
		if (data_check_match(ptr_a->data, ptr_b->data, mask)) {
			ptr_a = ptr_a->next;
			ptr_b = ptr_b->next;
		} else
			fail = true;
	}

	return !fail;
}

extern bool data_check_match(const data_t *a, const data_t *b, bool mask)
{
	bool rc;

	if (a == NULL && b == NULL)
		return true;

	if (a == NULL || b == NULL)
		return false;

	_check_magic(a);
	_check_magic(b);

	if (data_get_type(a) != data_get_type(b)) {
		data_t *conv = data_copy(data_new(), b);

		if ((a->type == TYPE_NULL) || (b->type == TYPE_NULL) ||
		    (data_convert_type(conv, data_get_type(a)) !=
		     data_get_type(a))) {
			log_flag(DATA, "type mismatch: %s(0x%"PRIXPTR") != %s(0x%"PRIXPTR")",
				 _type_to_string(a->type), (uintptr_t) a,
				 _type_to_string(b->type), (uintptr_t) b);
			FREE_NULL_DATA(conv);
			return false;
		}

		rc = data_check_match(a, conv, mask);
		log_flag(DATA, "compare: %pD %s %pD (converted from %pD)",
		         a, (rc ? "=" : "!="), conv, b);

		FREE_NULL_DATA(conv);
		return rc;
	}

	switch (a->type) {
	case TYPE_NULL:
		rc = (b->type == TYPE_NULL);
		log_flag(DATA, "compare: %s(0x%"PRIXPTR") %s %s(0x%"PRIXPTR")",
			 _type_to_string(a->type), (uintptr_t) a,
			 (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b);
		return rc;
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		rc = !xstrcmp(data_get_string(a), data_get_string(b));
		log_flag(DATA, "compare: %s(0x%"PRIXPTR")=%s %s %s(0x%"PRIXPTR")=%s",
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_string(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_string(b));
		return rc;
	case TYPE_BOOL:
		rc = (data_get_bool(a) == data_get_bool(b));
		log_flag(DATA, "compare: %s(0x%"PRIXPTR")=%s %s %s(0x%"PRIXPTR")=%s",
			 _type_to_string(a->type), (uintptr_t) a,
			 (data_get_bool(a) ? "True" : "False"),
			 (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 (data_get_bool(b) ? "True" : "False"));
		return rc;
	case TYPE_INT_64:
		rc = data_get_int(a) == data_get_int(b);
		log_flag(DATA, "compare: %s(0x%"PRIXPTR")=%"PRId64" %s %s(0x%"PRIXPTR")=%"PRId64,
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_int(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_int(b));
		return rc;
	case TYPE_FLOAT:
		if (!(rc = (data_get_float(a) == data_get_float(b))) ||
		    !(rc = fuzzy_equal(data_get_float(a), data_get_float(b)))) {
			if (isnan(data_get_float(a)) ==
			    isnan(data_get_float(a)))
				rc = true;
			else if (signbit(data_get_float(a)) !=
				 signbit(data_get_float(b)))
				rc = false;
			else if (isinf(data_get_float(a)) !=
				 isinf(data_get_float(b)))
				rc = false;
			else
				rc = false;
		}

		log_flag(DATA, "compare: %s(0x%"PRIXPTR")=%e %s %s(0x%"PRIXPTR")=%e",
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_float(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_float(b));
		return rc;
	case TYPE_DICT:
		rc = _data_match_dict(a, b, mask);
		log_flag(DATA, "compare dictionary: %s(0x%"PRIXPTR")[%zd] %s %s(0x%"PRIXPTR")[%zd]",
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_dict_length(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_dict_length(b));
		return rc;
	case TYPE_LIST:
		rc = _data_match_lists(a, b, mask);
		log_flag(DATA, "compare list: %s(0x%"PRIXPTR")[%zd] %s %s(0x%"PRIXPTR")[%zd]",
			 _type_to_string(a->type), (uintptr_t) a,
			 data_get_list_length(a), (rc ? "=" : "!="),
			 _type_to_string(b->type), (uintptr_t) b,
			 data_get_list_length(b));
		return rc;
	case TYPE_NONE:
		/* fall through */
	case TYPE_START:
		/* fall through */
	case TYPE_MAX:
		fatal_abort("%s: unexpected data type", __func__);
	}

	fatal_abort("%s: should never run", __func__);
}

extern data_t *data_resolve_dict_path(data_t *data, const char *path)
{
	data_t *found = data;
	char *save_ptr = NULL;
	char *token = NULL;
	char *str;
	char local[DATA_DEFINE_DICT_PATH_BUFFER_SIZE];
	size_t len = strlen(path);

	_check_magic(data);

	if (!data)
		return NULL;

	if (len < sizeof(local))
		str = memcpy(local, path, (len + 1));
	else
		str = xstrdup(path);

	token = strtok_r(str, "/", &save_ptr);
	while (token && found) {
		/* walk forward any whitespace */
		while (*token && isspace(*token))
			token++;

		/* zero any ending whitespace */
		for (int i = strlen(token) - 1; i >= 0; i--) {
			if (isspace(token[i]))
				token[i] = '\0';
			else
				break;
		}

		if (!found || (found->type != TYPE_DICT)) {
			found = NULL;
			break;
		}

		if (!(found = data_key_get(found, token)))
			break;

		token = strtok_r(NULL, "/", &save_ptr);
	}

	if (str != local)
		xfree(str);

	if (found)
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD resolved dictionary path to %pD",
			     __func__, data, found);
	else
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD failed to resolve dictionary path",
			     __func__, data);
	return found;
}

extern const data_t *data_resolve_dict_path_const(const data_t *data,
						  const char *path)
{
	const data_t *found = data;
	char *save_ptr = NULL;
	char *token = NULL;
	char *str;

	_check_magic(data);

	if (!data)
		return NULL;

	str = xstrdup(path);

	token = strtok_r(str, "/", &save_ptr);
	while (token && found) {
		xstrtrim(token);

		if (!found || (found->type != TYPE_DICT)) {
			found = NULL;
			break;
		}

		if (!(found = data_key_get_const(found, token)))
			break;

		token = strtok_r(NULL, "/", &save_ptr);
	}
	xfree(str);

	if (found)
		log_flag_hex(DATA, path, strlen(path),
			     "%s: data %pD resolved dictionary path to %pD",
			     __func__, data, found);
	else
		log_flag_hex(DATA, path, strlen(path),
			     "%s: data %pD failed to resolve dictionary path",
			     __func__, data);

	return found;
}

extern data_t *data_define_dict_path(data_t *data, const char *path)
{
	data_t *found = data;
	char *save_ptr = NULL;
	char *token = NULL;
	char *str;

	_check_magic(data);

	if (!data)
		return NULL;

	str = xstrdup(path);

	token = strtok_r(str, "/", &save_ptr);
	while (token && found) {
		xstrtrim(token);

		if (found->type == TYPE_NULL)
			data_set_dict(found);
		else if (found->type != TYPE_DICT) {
			found = NULL;
			break;
		}

		if (!(found = data_key_set(found, token)))
			break;

		token = strtok_r(NULL, "/", &save_ptr);
	}
	xfree(str);

	if (found)
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD defined dictionary path to %pD",
			     __func__, data, found);
	else
		log_flag_hex(DATA, path, strlen(path),
			     "%s: %pD failed to define dictionary path",
			     __func__, data);

	return found;
}

extern data_t *data_copy(data_t *dest, const data_t *src)
{
	if (!src)
		return NULL;

	if (!dest)
		dest = data_new();

	_check_magic(src);
	_check_magic(dest);

	log_flag(DATA, "%s: copy data %pD to %pD", __func__, src, dest);

	switch (src->type) {
	case TYPE_STRING_INLINE:
	case TYPE_STRING_PTR:
		return data_set_string(dest, data_get_string(src));
	case TYPE_BOOL:
		return data_set_bool(dest, data_get_bool(src));
	case TYPE_INT_64:
		return data_set_int(dest, data_get_int(src));
	case TYPE_FLOAT:
		return data_set_float(dest, data_get_float(src));
	case TYPE_NULL:
		return data_set_null(dest);
	case TYPE_LIST:
	{
		data_list_node_t *i = src->data.list_u->begin;

		data_set_list(dest);

		while (i) {
			_check_data_list_node_magic(i);
			xassert(!i->key);
			data_copy(data_list_append(dest), i->data);
			i = i->next;
		}

		return dest;
	}
	case TYPE_DICT:
	{
		data_list_node_t *i = src->data.dict_u->begin;

		data_set_dict(dest);

		while (i) {
			_check_data_list_node_magic(i);
			data_copy(data_key_set(dest, i->key), i->data);
			i = i->next;
		}

		return dest;
	}
	default:
		fatal_abort("%s: unexpected data type", __func__);
		return NULL;
	}
}

extern data_t *data_move(data_t *dest, data_t *src)
{
	if (!src)
		return NULL;

	if (!dest)
		dest = data_new();

	_check_magic(src);
	_check_magic(dest);

	log_flag(DATA, "%s: move data %pD to %pD", __func__, src, dest);

	memmove(&dest->data, &src->data, sizeof(src->data));
	dest->type = src->type;
	src->type = TYPE_NULL;

	return dest;
}

extern int data_retrieve_dict_path_string(const data_t *data, const char *path,
					  char **ptr_buffer)
{
	const data_t *d = NULL;
	int rc;

	_check_magic(data);
	if (!(d = data_resolve_dict_path_const(data, path)))
		return ESLURM_DATA_PATH_NOT_FOUND;

	rc = data_get_string_converted(d, ptr_buffer);

	if (rc)
		log_flag(DATA, "%s: data %pD failed to resolve string at path:%s",
			 __func__, data, path);
	else
		log_flag_hex(DATA, *ptr_buffer, strlen(*ptr_buffer),
			 "%s: data %pD resolved string at path:%s",
			 __func__, data, path);

	return rc;
}

extern int data_retrieve_dict_path_bool(const data_t *data, const char *path,
					bool *ptr_buffer)
{
	const data_t *d = NULL;
	int rc;

	_check_magic(data);
	if (!(d = data_resolve_dict_path_const(data, path)))
		return ESLURM_DATA_PATH_NOT_FOUND;

	rc = data_copy_bool_converted(d, ptr_buffer);

	log_flag(DATA, "%s: data %pD resolved string at path %s=%s: %s",
		 __func__, data, path,
		 (*ptr_buffer ? "true" : "false"), slurm_strerror(rc));

	return rc;
}

extern int data_retrieve_dict_path_int(const data_t *data, const char *path,
				       int64_t *ptr_buffer)
{
	const data_t *d = NULL;
	int rc;

	_check_magic(data);
	if (!(d = data_resolve_dict_path_const(data, path)))
		return ESLURM_DATA_PATH_NOT_FOUND;

	rc = data_get_int_converted(d, ptr_buffer);

	log_flag(DATA, "%s: data %pD resolved string at path %s to %"PRId64": %s",
		 __func__, data, path, *ptr_buffer, slurm_strerror(rc));

	return rc;
}

static char *_type_to_string(type_t type)
{
	return data_type_to_string((int) type);
}

extern char *data_type_to_string(data_type_t type)
{
	switch(type) {
		case DATA_TYPE_NULL:
			return "null";
		case DATA_TYPE_LIST:
			return "list";
		case DATA_TYPE_DICT:
			return "dictionary";
		case DATA_TYPE_INT_64:
			return "64 bit integer";
		case DATA_TYPE_STRING:
			return "string";
		case DATA_TYPE_FLOAT:
			return "floating point number";
		case DATA_TYPE_BOOL:
			return "boolean";
		case DATA_TYPE_NONE:
			/* fall through */
		case DATA_TYPE_MAX:
			return "INVALID";
	}

	for (int i = 0; i < ARRAY_SIZE(type_map); i++) {
		if (type_map[i].internal_type == (int) type)
			return data_type_to_string(type_map[i].external_type);
	}

	return "INVALID";
}

extern const char *data_get_type_string(const data_t *data)
{
	if (!data)
		return "INVALID";

	for (int i = 0; i < ARRAY_SIZE(type_map); i++)
		if (type_map[i].internal_type == data->type)
			return data_type_to_string(type_map[i].external_type);

	xassert(false);
	return "INVALID";
}
