/*
 * Copyright 2006 Juan Lang
 *
 * 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 <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wine/debug.h"
#include "wine/list.h"
#include "crypt32_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(context);

typedef enum _ContextType {
    ContextTypeData,
    ContextTypeLink,
} ContextType;

typedef struct _BASE_CONTEXT
{
    LONG        ref;
    ContextType type;
} BASE_CONTEXT, *PBASE_CONTEXT;

typedef struct _DATA_CONTEXT
{
    LONG                   ref;
    ContextType            type; /* always ContextTypeData */
    PCONTEXT_PROPERTY_LIST properties;
} DATA_CONTEXT, *PDATA_CONTEXT;

typedef struct _LINK_CONTEXT
{
    LONG          ref;
    ContextType   type; /* always ContextTypeLink */
    PBASE_CONTEXT linked;
} LINK_CONTEXT, *PLINK_CONTEXT;

#define CONTEXT_FROM_BASE_CONTEXT(p, s) ((LPBYTE)(p) - (s))
#define BASE_CONTEXT_FROM_CONTEXT(p, s) (PBASE_CONTEXT)((LPBYTE)(p) + (s))

void *Context_CreateDataContext(size_t contextSize)
{
    void *ret = CryptMemAlloc(contextSize + sizeof(DATA_CONTEXT));

    if (ret)
    {
        PDATA_CONTEXT context = (PDATA_CONTEXT)((LPBYTE)ret + contextSize);

        context->ref = 1;
        context->type = ContextTypeData;
        context->properties = ContextPropertyList_Create();
        if (!context->properties)
        {
            CryptMemFree(ret);
            ret = NULL;
        }
    }
    TRACE("returning %p\n", ret);
    return ret;
}

void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned int extra,
 BOOL addRef)
{
    void *context = CryptMemAlloc(contextSize + sizeof(LINK_CONTEXT) + extra);

    TRACE("(%d, %p, %d)\n", contextSize, linked, extra);

    if (context)
    {
        PLINK_CONTEXT linkContext = (PLINK_CONTEXT)BASE_CONTEXT_FROM_CONTEXT(
         context, contextSize);
        PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linked,
         contextSize);

        memcpy(context, linked, contextSize);
        linkContext->ref = 1;
        linkContext->type = ContextTypeLink;
        linkContext->linked = linkedBase;
        if (addRef)
            Context_AddRef(linked, contextSize);
        TRACE("%p's ref count is %d\n", context, linkContext->ref);
    }
    TRACE("returning %p\n", context);
    return context;
}

void Context_AddRef(void *context, size_t contextSize)
{
    PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);

    InterlockedIncrement(&baseContext->ref);
    TRACE("%p's ref count is %d\n", context, baseContext->ref);
    if (baseContext->type == ContextTypeLink)
    {
        void *linkedContext = Context_GetLinkedContext(context, contextSize);
        PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
         contextSize);

        /* Add-ref the linked contexts too */
        while (linkedContext && linkedBase->type == ContextTypeLink)
        {
            InterlockedIncrement(&linkedBase->ref);
            TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref);
            linkedContext = Context_GetLinkedContext(linkedContext,
             contextSize);
            if (linkedContext)
                linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
                 contextSize);
            else
                linkedBase = NULL;
        }
        if (linkedContext)
        {
            /* It's not a link context, so it wasn't add-ref'ed in the while
             * loop, so add-ref it here.
             */
            linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext,
             contextSize);
            InterlockedIncrement(&linkedBase->ref);
            TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref);
        }
    }
}

void *Context_GetExtra(const void *context, size_t contextSize)
{
    PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);

    assert(baseContext->type == ContextTypeLink);
    return (LPBYTE)baseContext + sizeof(LINK_CONTEXT);
}

void *Context_GetLinkedContext(void *context, size_t contextSize)
{
    PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);

    assert(baseContext->type == ContextTypeLink);
    return CONTEXT_FROM_BASE_CONTEXT(((PLINK_CONTEXT)baseContext)->linked,
     contextSize);
}

PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t contextSize)
{
    PBASE_CONTEXT ptr = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);

    while (ptr && ptr->type == ContextTypeLink)
        ptr = ((PLINK_CONTEXT)ptr)->linked;
    return (ptr && ptr->type == ContextTypeData) ?
     ((PDATA_CONTEXT)ptr)->properties : NULL;
}

BOOL Context_Release(void *context, size_t contextSize,
 ContextFreeFunc dataContextFree)
{
    PBASE_CONTEXT base = BASE_CONTEXT_FROM_CONTEXT(context, contextSize);
    BOOL ret = TRUE;

    if (base->ref <= 0)
    {
        ERR("%p's ref count is %d\n", context, base->ref);
        return FALSE;
    }
    if (base->type == ContextTypeLink)
    {
        /* The linked context is of the same type as this, so release
         * it as well, using the same offset and data free function.
         */
        ret = Context_Release(CONTEXT_FROM_BASE_CONTEXT(
         ((PLINK_CONTEXT)base)->linked, contextSize), contextSize,
         dataContextFree);
    }
    if (InterlockedDecrement(&base->ref) == 0)
    {
        TRACE("freeing %p\n", context);
        if (base->type == ContextTypeData)
        {
            ContextPropertyList_Free(((PDATA_CONTEXT)base)->properties);
            dataContextFree(context);
        }
        CryptMemFree(context);
    }
    else
        TRACE("%p's ref count is %d\n", context, base->ref);
    return ret;
}

void Context_CopyProperties(const void *to, const void *from,
 size_t contextSize)
{
    PCONTEXT_PROPERTY_LIST toProperties, fromProperties;

    toProperties = Context_GetProperties(to, contextSize);
    fromProperties = Context_GetProperties(from, contextSize);
    assert(toProperties && fromProperties);
    ContextPropertyList_Copy(toProperties, fromProperties);
}

struct ContextList
{
    PCWINE_CONTEXT_INTERFACE contextInterface;
    size_t contextSize;
    CRITICAL_SECTION cs;
    struct list contexts;
};

struct ContextList *ContextList_Create(
 PCWINE_CONTEXT_INTERFACE contextInterface, size_t contextSize)
{
    struct ContextList *list = CryptMemAlloc(sizeof(struct ContextList));

    if (list)
    {
        list->contextInterface = contextInterface;
        list->contextSize = contextSize;
        InitializeCriticalSection(&list->cs);
        list->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ContextList.cs");
        list_init(&list->contexts);
    }
    return list;
}

static inline struct list *ContextList_ContextToEntry(const struct ContextList *list,
 const void *context)
{
    struct list *ret;

    if (context)
        ret = Context_GetExtra(context, list->contextSize);
    else
        ret = NULL;
    return ret;
}

static inline void *ContextList_EntryToContext(const struct ContextList *list,
 struct list *entry)
{
    return (LPBYTE)entry - sizeof(LINK_CONTEXT) - list->contextSize;
}

void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace)
{
    void *context;

    TRACE("(%p, %p, %p)\n", list, toLink, toReplace);

    context = Context_CreateLinkContext(list->contextSize, toLink,
     sizeof(struct list), TRUE);
    if (context)
    {
        struct list *entry = ContextList_ContextToEntry(list, context);

        TRACE("adding %p\n", context);
        EnterCriticalSection(&list->cs);
        if (toReplace)
        {
            struct list *existing = ContextList_ContextToEntry(list, toReplace);

            entry->prev = existing->prev;
            entry->next = existing->next;
            entry->prev->next = entry;
            entry->next->prev = entry;
            existing->prev = existing->next = existing;
            list->contextInterface->free(toReplace);
        }
        else
            list_add_head(&list->contexts, entry);
        LeaveCriticalSection(&list->cs);
    }
    return context;
}

void *ContextList_Enum(struct ContextList *list, void *pPrev)
{
    struct list *listNext;
    void *ret;

    EnterCriticalSection(&list->cs);
    if (pPrev)
    {
        struct list *prevEntry = ContextList_ContextToEntry(list, pPrev);

        listNext = list_next(&list->contexts, prevEntry);
        list->contextInterface->free(pPrev);
    }
    else
        listNext = list_next(&list->contexts, &list->contexts);
    LeaveCriticalSection(&list->cs);

    if (listNext)
    {
        ret = ContextList_EntryToContext(list, listNext);
        list->contextInterface->duplicate(ret);
    }
    else
        ret = NULL;
    return ret;
}

BOOL ContextList_Remove(struct ContextList *list, void *context)
{
    struct list *entry = ContextList_ContextToEntry(list, context);
    BOOL inList = FALSE;

    EnterCriticalSection(&list->cs);
    if (!list_empty(entry))
    {
        list_remove(entry);
        inList = TRUE;
    }
    LeaveCriticalSection(&list->cs);
    if (inList)
        list_init(entry);
    return inList;
}

static void ContextList_Empty(struct ContextList *list)
{
    struct list *entry, *next;

    EnterCriticalSection(&list->cs);
    LIST_FOR_EACH_SAFE(entry, next, &list->contexts)
    {
        const void *context = ContextList_EntryToContext(list, entry);

        TRACE("removing %p\n", context);
        list_remove(entry);
        list->contextInterface->free(context);
    }
    LeaveCriticalSection(&list->cs);
}

void ContextList_Free(struct ContextList *list)
{
    ContextList_Empty(list);
    list->cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&list->cs);
    CryptMemFree(list);
}
