/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_INCLUDE_MISC_LIST_GEN_H_
#define ZEPHYR_INCLUDE_MISC_LIST_GEN_H_

#include <stddef.h>
#include <stdbool.h>
#include <misc/util.h>

#define Z_GENLIST_FOR_EACH_NODE(__lname, __l, __sn)			\
	for (__sn = sys_ ## __lname ## _peek_head(__l); __sn != NULL;	\
	     __sn = sys_ ## __lname ## _peek_next(__sn))


#define Z_GENLIST_ITERATE_FROM_NODE(__lname, __l, __sn)			\
	for (__sn = __sn ? sys_ ## __lname ## _peek_next_no_check(__sn)	\
			 : sys_ ## __lname ## _peek_head(__l);		\
	     __sn != NULL;						\
	     __sn = sys_ ## __lname ## _peek_next(__sn))

#define Z_GENLIST_FOR_EACH_NODE_SAFE(__lname, __l, __sn, __sns)		\
	for (__sn = sys_ ## __lname ## _peek_head(__l),			\
		     __sns = sys_ ## __lname ## _peek_next(__sn);	\
	     __sn != NULL ; __sn = __sns,				\
		     __sns = sys_ ## __lname ## _peek_next(__sn))

#define Z_GENLIST_CONTAINER(__ln, __cn, __n)				\
	((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)

#define Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n)		\
	Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_head(__l), __cn, __n)

#define Z_GENLIST_PEEK_TAIL_CONTAINER(__lname, __l, __cn, __n)		\
	Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_tail(__l), __cn, __n)

#define Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n)		\
	((__cn) ? Z_GENLIST_CONTAINER(					\
			sys_ ## __lname ## _peek_next(&((__cn)->__n)),	\
			__cn, __n) : NULL)

#define Z_GENLIST_FOR_EACH_CONTAINER(__lname, __l, __cn, __n)		\
	for (__cn = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn,	\
						  __n);			\
	     __cn != NULL;						\
	     __cn = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))

#define Z_GENLIST_FOR_EACH_CONTAINER_SAFE(__lname, __l, __cn, __cns, __n)     \
	for (__cn = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n),   \
	     __cns = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n); \
	     __cn != NULL; __cn = __cns,				\
	     __cns = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))

#define Z_GENLIST_IS_EMPTY(__lname)					\
	static inline bool						\
	sys_ ## __lname ## _is_empty(sys_ ## __lname ## _t *list)	\
	{								\
		return (!sys_ ## __lname ## _peek_head(list));		\
	}

#define Z_GENLIST_PEEK_NEXT_NO_CHECK(__lname, __nname)			    \
	static inline sys_ ## __nname ## _t *				    \
	sys_ ## __lname ## _peek_next_no_check(sys_ ## __nname ## _t *node) \
	{								    \
		return z_ ## __nname ## _next_peek(node);		    \
	}

#define Z_GENLIST_PEEK_NEXT(__lname, __nname)				     \
	static inline sys_ ## __nname ## _t *				     \
	sys_ ## __lname ## _peek_next(sys_ ## __nname ## _t *node)	     \
	{								     \
		return node ? sys_ ## __lname ## _peek_next_no_check(node) : \
			      NULL;					     \
	}

#define Z_GENLIST_PREPEND(__lname, __nname)				      \
	static inline void						      \
	sys_ ## __lname ## _prepend(sys_ ## __lname ## _t *list,	      \
				    sys_ ## __nname ## _t *node)	      \
	{								      \
		z_ ## __nname ## _next_set(node,			      \
					sys_ ## __lname ## _peek_head(list)); \
		z_ ## __lname ## _head_set(list, node);			      \
									      \
		if (!sys_ ## __lname ## _peek_tail(list)) {		      \
			z_ ## __lname ## _tail_set(list,		      \
					sys_ ## __lname ## _peek_head(list)); \
		}							      \
	}

#define Z_GENLIST_APPEND(__lname, __nname)				\
	static inline void						\
	sys_ ## __lname ## _append(sys_ ## __lname ## _t *list,		\
				   sys_ ## __nname ## _t *node)		\
	{								\
		z_ ## __nname ## _next_set(node, NULL);			\
									\
		if (!sys_ ## __lname ## _peek_tail(list)) {		\
			z_ ## __lname ## _tail_set(list, node);		\
			z_ ## __lname ## _head_set(list, node);		\
		} else {						\
			z_ ## __nname ## _next_set(			\
				sys_ ## __lname ## _peek_tail(list),	\
				node);					\
			z_ ## __lname ## _tail_set(list, node);		\
		}							\
	}

#define Z_GENLIST_APPEND_LIST(__lname, __nname)				\
	static inline void						\
	sys_ ## __lname ## _append_list(sys_ ## __lname ## _t *list,	\
					void *head, void *tail)		\
{									\
	if (!sys_ ## __lname ## _peek_tail(list)) {			\
		z_ ## __lname ## _head_set(list,			\
					(sys_ ## __nname ## _t *)head); \
	} else {							\
		z_ ## __nname ## _next_set(				\
			sys_ ## __lname ## _peek_tail(list),		\
			(sys_ ## __nname ## _t *)head);			\
	}								\
	z_ ## __lname ## _tail_set(list,				\
				     (sys_ ## __nname ## _t *)tail);	\
}

#define Z_GENLIST_MERGE_LIST(__lname, __nname)				\
	static inline void						\
	sys_ ## __lname ## _merge_ ## __lname (				\
				sys_ ## __lname ## _t *list,		\
				sys_ ## __lname ## _t *list_to_append)	\
	{								\
		sys_ ## __nname ## _t *head, *tail;			\
		head = sys_ ## __lname ## _peek_head(list_to_append);	\
		tail = sys_ ## __lname ## _peek_tail(list_to_append);	\
		sys_ ## __lname ## _append_list(list, head, tail);	\
		sys_ ## __lname ## _init(list_to_append);		\
	}

#define Z_GENLIST_INSERT(__lname, __nname)				\
	static inline void						\
	sys_ ## __lname ## _insert(sys_ ## __lname ## _t *list,		\
				   sys_ ## __nname ## _t *prev,		\
				   sys_ ## __nname ## _t *node)		\
	{								\
		if (!prev) {						\
			sys_ ## __lname ## _prepend(list, node);	\
		} else if (!z_ ## __nname ## _next_peek(prev)) {	\
			sys_ ## __lname ## _append(list, node);		\
		} else {						\
			z_ ## __nname ## _next_set(node,		\
				z_ ## __nname ## _next_peek(prev));	\
			z_ ## __nname ## _next_set(prev, node);		\
		}							\
	}

#define Z_GENLIST_GET_NOT_EMPTY(__lname, __nname)			\
	static inline sys_ ## __nname ## _t *				\
	sys_ ## __lname ## _get_not_empty(sys_ ## __lname ## _t *list)	\
	{								\
		sys_ ## __nname ## _t *node =				\
				sys_ ## __lname ## _peek_head(list);	\
									\
		z_ ## __lname ## _head_set(list,			\
				z_ ## __nname ## _next_peek(node));	\
		if (sys_ ## __lname ## _peek_tail(list) == node) {	\
			z_ ## __lname ## _tail_set(list,		\
				sys_ ## __lname ## _peek_head(list));	\
		}							\
									\
		return node;						\
	}

#define Z_GENLIST_GET(__lname, __nname)					\
	static inline sys_ ## __nname ## _t *				\
	sys_ ## __lname ## _get(sys_ ## __lname ## _t *list)		\
	{								\
		return sys_ ## __lname ## _is_empty(list) ? NULL :	\
			sys_ ## __lname ## _get_not_empty(list);	\
	}

#define Z_GENLIST_REMOVE(__lname, __nname)				      \
	static inline void						      \
	sys_ ## __lname ## _remove(sys_ ## __lname ## _t *list,		      \
				   sys_ ## __nname ## _t *prev_node,	      \
				   sys_ ## __nname ## _t *node)		      \
	{								      \
		if (!prev_node) {					      \
			z_ ## __lname ## _head_set(list,		      \
				z_ ## __nname ## _next_peek(node));	      \
									      \
			/* Was node also the tail? */			      \
			if (sys_ ## __lname ## _peek_tail(list) == node) {    \
				z_ ## __lname ## _tail_set(list,	      \
					sys_ ## __lname ## _peek_head(list)); \
			}						      \
		} else {						      \
			z_ ## __nname ## _next_set(prev_node,		      \
				z_ ## __nname ## _next_peek(node));	      \
									      \
			/* Was node the tail? */			      \
			if (sys_ ## __lname ## _peek_tail(list) == node) {    \
				z_ ## __lname ## _tail_set(list,	      \
							     prev_node);      \
			}						      \
		}							      \
									      \
		z_ ## __nname ## _next_set(node, NULL);			      \
	}

#define Z_GENLIST_FIND_AND_REMOVE(__lname, __nname)			 \
	static inline bool						 \
	sys_ ## __lname ## _find_and_remove(sys_ ## __lname ## _t *list, \
					    sys_ ## __nname ## _t *node) \
	{								 \
		sys_ ## __nname ## _t *prev = NULL;			 \
		sys_ ## __nname ## _t *test;				 \
									 \
		Z_GENLIST_FOR_EACH_NODE(__lname, list, test) {		 \
			if (test == node) {				 \
				sys_ ## __lname ## _remove(list, prev,	 \
							   node);	 \
				return true;				 \
			}						 \
									 \
			prev = test;					 \
		}							 \
									 \
		return false;						 \
	}

#endif /* ZEPHYR_INCLUDE_MISC_LIST_GEN_H_ */
