/*
 * Web Services on Devices
 *
 * Copyright 2017 Owen Rudge for CodeWeavers
 *
 * 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
 */

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "wine/list.h"
#include "wsdapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);

#define MEMORY_ALLOCATION_MAGIC     0xB10C5EED

#define ALIGNMENT                   (2 * sizeof(void*))
#define ROUND_TO_ALIGNMENT(size)    (((size) + ALIGNMENT - 1) & ~(ALIGNMENT - 1))
#define MEMORY_ALLOCATION_SIZE      ROUND_TO_ALIGNMENT(sizeof(struct memory_allocation))

struct memory_allocation
{
    int magic;
    struct list entry;

    struct list children;
};

static struct memory_allocation *find_allocation(void *ptr)
{
    struct memory_allocation *allocation;

    if (ptr == NULL)
    {
        return NULL;
    }

    allocation = (struct memory_allocation *)((char *)ptr - MEMORY_ALLOCATION_SIZE);

    if (allocation->magic != MEMORY_ALLOCATION_MAGIC)
    {
        return NULL;
    }

    return allocation;
}

static void free_allocation(struct memory_allocation *item)
{
    struct memory_allocation *child, *cursor;

    LIST_FOR_EACH_ENTRY_SAFE(child, cursor, &item->children, struct memory_allocation, entry)
    {
        free_allocation(child);
    }

    list_remove(&item->entry);
    item->magic = 0;
    HeapFree(GetProcessHeap(), 0, item);
}

void * WINAPI WSDAllocateLinkedMemory(void *pParent, SIZE_T cbSize)
{
    struct memory_allocation *allocation, *parent;
    void *ptr;

    TRACE("(%p, %lu)\n", pParent, cbSize);

    ptr = HeapAlloc(GetProcessHeap(), 0, MEMORY_ALLOCATION_SIZE + cbSize);

    if (ptr == NULL)
    {
        return NULL;
    }

    allocation = ptr;
    allocation->magic = MEMORY_ALLOCATION_MAGIC;

    list_init(&allocation->children);

    /* See if we have a parent */
    parent = find_allocation(pParent);

    if (parent != NULL)
    {
        list_add_tail(&parent->children, &allocation->entry);
    }
    else
    {
        list_init(&allocation->entry);
    }

    return (char *)ptr + MEMORY_ALLOCATION_SIZE;
}

void WINAPI WSDAttachLinkedMemory(void *pParent, void *pChild)
{
    struct memory_allocation *parent, *child;

    TRACE("(%p, %p)\n", pParent, pChild);

    child = find_allocation(pChild);
    parent = find_allocation(pParent);

    TRACE("child: %p, parent: %p\n", child, parent);

    if ((child == NULL) || (parent == NULL))
    {
        return;
    }

    list_remove(&child->entry);
    list_add_tail(&parent->children, &child->entry);
}

void WINAPI WSDDetachLinkedMemory(void *pVoid)
{
    struct memory_allocation *allocation;

    TRACE("(%p)\n", pVoid);

    allocation = find_allocation(pVoid);

    if (allocation == NULL)
    {
        TRACE("Memory allocation not found\n");
        return;
    }

    list_remove(&allocation->entry);
}

void WINAPI WSDFreeLinkedMemory(void *pVoid)
{
    struct memory_allocation *allocation;

    TRACE("(%p)\n", pVoid);

    allocation = find_allocation(pVoid);

    if (allocation == NULL)
    {
        TRACE("Memory allocation not found\n");
        return;
    }

    free_allocation(allocation);
}
