#ifndef _INTRUSIVE_LL_LIBRARY_H_
#define _INTRUSIVE_LL_LIBRARY_H_
// These are include guards, which prevent the contents of the header file 
// from being included multiple times in a single compilation unit. 
// This can help avoid issues like redefinition errors and reduce compilation time.

#include <Windows.h>

typedef struct _NODE NODE;
typedef struct _NODE* PNODE;

struct _NODE
{
    PNODE pPrev;
    PNODE pNext;
};

typedef struct _LIST_HEAD
{
    PNODE pHead;
    PNODE pTail;
    CRITICAL_SECTION Lock; // Lock to protect concurrent access to the list.

} LIST_HEAD, * PLIST_HEAD;

// InitializeListHead
// Description: Initializes a list head structure to represent an empty doubly linked list.
//              Initializes the critical section lock for thread-safe access.
//              Must be called before any other list operations.
// Input:       pListHead - Pointer to the LIST_HEAD structure to initialize.
// Output:      None (VOID). The LIST_HEAD's pHead and pTail are set to NULL.
VOID InitializeListHead( _Out_ PLIST_HEAD pListHead);

// DestroyListHead
// Description: Cleans up resources associated with the list head, including the critical section.
//              Must be called when the list is no longer needed.
// Input:       pListHead - Pointer to the LIST_HEAD structure to destroy.
// Output:      None (VOID).
VOID DestroyListHead( _Inout_ PLIST_HEAD pListHead);

// AddHead
// Description: Inserts a node at the beginning (head) of the doubly linked list.
//              If the list is empty, the node becomes both the head and the tail.
// Input:       pListHead - Pointer to the LIST_HEAD structure managing the list.
//              pEntry    - Pointer to the NODE to insert at the head.
// Output:      None (VOID). The list is updated in place.
VOID AddHead( _Inout_ PLIST_HEAD pListHead, _In_ PNODE pEntry);

// AddTail
// Description: Appends a node at the end (tail) of the doubly linked list.
//              If the list is empty, the node becomes both the head and the tail.
// Input:       pListHead - Pointer to the LIST_HEAD structure managing the list.
//              pEntry    - Pointer to the NODE to insert at the tail.
// Output:      None (VOID). The list is updated in place.
VOID AddTail( _Inout_ PLIST_HEAD pListHead, _In_ PNODE pEntry);

// RemoveHead
// Description: Removes the node at the head of the list and returns it.
//              The removed node's pPrev and pNext pointers are set to NULL.
// Input:       pListHead - Pointer to the LIST_HEAD structure managing the list.
// Output:      Returns a PNODE pointer to the removed head node, or NULL if the list is empty.
PNODE RemoveHead( _Inout_ PLIST_HEAD pListHead);

// RemoveTail
// Description: Removes the node at the tail of the list and returns it.
//              The removed node's pPrev and pNext pointers are set to NULL.
// Input:       pListHead - Pointer to the LIST_HEAD structure managing the list.
// Output:      Returns a PNODE pointer to the removed tail node, or NULL if the list is empty.
PNODE RemoveTail( _Inout_ PLIST_HEAD pListHead);

// SearchNode
// Description: Traverses the list from head to tail searching for a specific node by pointer equality.
// Input:       pListHead - Pointer to the LIST_HEAD structure managing the list.
//              pEntry    - Pointer to the NODE to search for in the list.
// Output:      Returns the PNODE pointer if found in the list, or NULL if not found.
PNODE SearchNode( _In_ PLIST_HEAD pListHead, _In_ PNODE pEntry);

#endif