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

#ifndef ZEPHYR_MISC_LIST_GEN_H
#define ZEPHYR_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;		\
	     __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;							\
	     __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; __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;							\
	     __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; \
	     __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)					\
	static inline void						\
	sys_ ## __lname ## _merge_ ## __lname (				\
				sys_ ## __lname ## _t *list,		\
				sys_ ## __lname ## _t *list_to_append)	\
	{								\
		sys_ ## __lname ## _append_list(list,			\
			sys_ ## __lname ## _peek_head(list_to_append),	\
			sys_ ## __lname ## _peek_tail(list_to_append));	\
		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_MISC_LIST_GEN_H */
