/*
 * Copyright 2004-2007 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 <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wine/debug.h"
#include "crypt32_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(crypt);

typedef struct _WINE_STORE_LIST_ENTRY
{
    WINECRYPT_CERTSTORE *store;
    DWORD                dwUpdateFlags;
    DWORD                dwPriority;
    struct list          entry;
} WINE_STORE_LIST_ENTRY;

typedef struct _WINE_COLLECTIONSTORE
{
    WINECRYPT_CERTSTORE hdr;
    CRITICAL_SECTION    cs;
    struct list         stores;
} WINE_COLLECTIONSTORE;

static void Collection_addref(WINECRYPT_CERTSTORE *store)
{
    LONG ref = InterlockedIncrement(&store->ref);
    TRACE("ref = %d\n", ref);
}

static DWORD Collection_release(WINECRYPT_CERTSTORE *store, DWORD flags)
{
    WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
    WINE_STORE_LIST_ENTRY *entry, *next;
    LONG ref;

    if(flags)
        FIXME("Unimplemented flags %x\n", flags);

    ref = InterlockedDecrement(&cs->hdr.ref);
    TRACE("(%p) ref=%d\n", store, ref);
    if(ref)
        return ERROR_SUCCESS;

    LIST_FOR_EACH_ENTRY_SAFE(entry, next, &cs->stores, WINE_STORE_LIST_ENTRY, entry)
    {
        TRACE("closing %p\n", entry);
        entry->store->vtbl->release(entry->store, flags);
        CryptMemFree(entry);
    }
    cs->cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&cs->cs);
    CRYPT_FreeStore(store);
    return ERROR_SUCCESS;
}

static void Collection_releaseContext(WINECRYPT_CERTSTORE *store, context_t *context)
{
    /* We don't cache context links, so just free them. */
    Context_Free(context);
}

static context_t *CRYPT_CollectionCreateContextFromChild(WINE_COLLECTIONSTORE *store,
 WINE_STORE_LIST_ENTRY *storeEntry, context_t *child)
{
    context_t *ret;

    ret = child->vtbl->clone(child, &store->hdr, TRUE);
    if (!ret)
        return NULL;

    ret->u.ptr = storeEntry;
    return ret;
}

static BOOL CRYPT_CollectionAddContext(WINE_COLLECTIONSTORE *store,
 unsigned int contextFuncsOffset, context_t *context, context_t *toReplace,
 context_t **pChildContext)
{
    BOOL ret;
    context_t *childContext = NULL;
    WINE_STORE_LIST_ENTRY *storeEntry = NULL;

    TRACE("(%p, %d, %p, %p)\n", store, contextFuncsOffset, context, toReplace);

    ret = FALSE;
    if (toReplace)
    {
        context_t *existingLinked = toReplace->linked;
        CONTEXT_FUNCS *contextFuncs;

        storeEntry = toReplace->u.ptr;
        contextFuncs = (CONTEXT_FUNCS*)((LPBYTE)storeEntry->store->vtbl +
         contextFuncsOffset);
        ret = contextFuncs->addContext(storeEntry->store, context,
         existingLinked, &childContext, TRUE);
    }
    else
    {
        WINE_STORE_LIST_ENTRY *entry, *next;

        EnterCriticalSection(&store->cs);
        LIST_FOR_EACH_ENTRY_SAFE(entry, next, &store->stores, WINE_STORE_LIST_ENTRY, entry)
        {
            if (entry->dwUpdateFlags & CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG)
            {
                CONTEXT_FUNCS *contextFuncs = (CONTEXT_FUNCS*)(
                 (LPBYTE)entry->store->vtbl + contextFuncsOffset);

                storeEntry = entry;
                ret = contextFuncs->addContext(entry->store, context, NULL, &childContext, TRUE);
                break;
            }
        }
        LeaveCriticalSection(&store->cs);
        if (!storeEntry)
            SetLastError(E_ACCESSDENIED);
    }
    *pChildContext = childContext;
    return ret;
}

/* Advances a collection enumeration by one context, if possible, where
 * advancing means:
 * - calling the current store's enumeration function once, and returning
 *   the enumerated context if one is returned
 * - moving to the next store if the current store has no more items, and
 *   recursively calling itself to get the next item.
 * Returns NULL if the collection contains no more items or on error.
 * Assumes the collection store's lock is held.
 */
static context_t *CRYPT_CollectionAdvanceEnum(WINE_COLLECTIONSTORE *store,
 WINE_STORE_LIST_ENTRY *storeEntry, const CONTEXT_FUNCS *contextFuncs,
 context_t *prev)
{
    context_t *child, *ret;
    struct list *storeNext = list_next(&store->stores, &storeEntry->entry);

    TRACE("(%p, %p, %p)\n", store, storeEntry, prev);

    if (prev)
    {
        /* Ref-counting funny business: "duplicate" (addref) the child, because
         * the free(pPrev) below can cause the ref count to become negative.
         */
        child = prev->linked;
        Context_AddRef(child);
        child = contextFuncs->enumContext(storeEntry->store, child);
        Context_Release(prev);
        prev = NULL;
    }
    else
    {
        child = contextFuncs->enumContext(storeEntry->store, NULL);
    }
    if (child) {
        ret = CRYPT_CollectionCreateContextFromChild(store, storeEntry, child);
        Context_Release(child);
    }
    else
    {
        if (storeNext)
        {
            /* We always want the same function pointers (from certs, crls)
             * in the next store, so use the same offset into the next store.
             */
            size_t offset = (const BYTE *)contextFuncs - (LPBYTE)storeEntry->store->vtbl;
            WINE_STORE_LIST_ENTRY *storeNextEntry =
             LIST_ENTRY(storeNext, WINE_STORE_LIST_ENTRY, entry);
            CONTEXT_FUNCS *storeNextContexts =
             (CONTEXT_FUNCS*)((LPBYTE)storeNextEntry->store->vtbl + offset);

            ret = CRYPT_CollectionAdvanceEnum(store, storeNextEntry,
             storeNextContexts, NULL);
        }
        else
        {
            SetLastError(CRYPT_E_NOT_FOUND);
            ret = NULL;
        }
    }
    TRACE("returning %p\n", ret);
    return ret;
}

static BOOL Collection_addCert(WINECRYPT_CERTSTORE *store, context_t *cert,
 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
{
    BOOL ret;
    context_t *childContext = NULL;
    WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;

    ret = CRYPT_CollectionAddContext(cs, offsetof(store_vtbl_t, certs),
     cert, toReplace, &childContext);
    if (ppStoreContext && childContext)
    {
        WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
        cert_t *context = (cert_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
         childContext);

        *ppStoreContext = &context->base;
    }
    if (childContext)
        Context_Release(childContext);
    return ret;
}

static context_t *Collection_enumCert(WINECRYPT_CERTSTORE *store, context_t *prev)
{
    WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
    context_t *ret;

    TRACE("(%p, %p)\n", store, prev);

    EnterCriticalSection(&cs->cs);
    if (prev)
    {
        WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;

        ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
         &storeEntry->store->vtbl->certs, prev);
    }
    else
    {
        if (!list_empty(&cs->stores))
        {
            WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
             WINE_STORE_LIST_ENTRY, entry);

            ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
             &storeEntry->store->vtbl->certs, NULL);
        }
        else
        {
            SetLastError(CRYPT_E_NOT_FOUND);
            ret = NULL;
        }
    }
    LeaveCriticalSection(&cs->cs);
    TRACE("returning %p\n", ret);
    return ret;
}

static BOOL Collection_deleteCert(WINECRYPT_CERTSTORE *store, context_t *context)
{
    cert_t *cert = (cert_t*)context;
    cert_t *linked;

    TRACE("(%p, %p)\n", store, cert);

    linked = (cert_t*)context->linked;
    return CertDeleteCertificateFromStore(&linked->ctx);
}

static BOOL Collection_addCRL(WINECRYPT_CERTSTORE *store, context_t *crl,
 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
{
    BOOL ret;
    context_t *childContext = NULL;
    WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;

    ret = CRYPT_CollectionAddContext(cs, offsetof(store_vtbl_t, crls),
     crl, toReplace, &childContext);
    if (ppStoreContext && childContext)
    {
        WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
        crl_t *context = (crl_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
         childContext);

        *ppStoreContext = &context->base;
    }
    if (childContext)
        Context_Release(childContext);
    return ret;
}

static context_t *Collection_enumCRL(WINECRYPT_CERTSTORE *store, context_t *prev)
{
    WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
    context_t *ret;

    TRACE("(%p, %p)\n", store, prev);

    EnterCriticalSection(&cs->cs);
    if (prev)
    {
        WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;

        ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
         &storeEntry->store->vtbl->crls, prev);
    }
    else
    {
        if (!list_empty(&cs->stores))
        {
            WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
             WINE_STORE_LIST_ENTRY, entry);

            ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
             &storeEntry->store->vtbl->crls, NULL);
        }
        else
        {
            SetLastError(CRYPT_E_NOT_FOUND);
            ret = NULL;
        }
    }
    LeaveCriticalSection(&cs->cs);
    TRACE("returning %p\n", ret);
    return ret;
}

static BOOL Collection_deleteCRL(WINECRYPT_CERTSTORE *store, context_t *context)
{
    crl_t *crl = (crl_t*)context, *linked;

    TRACE("(%p, %p)\n", store, crl);

    linked = (crl_t*)context->linked;
    return CertDeleteCRLFromStore(&linked->ctx);
}

static BOOL Collection_addCTL(WINECRYPT_CERTSTORE *store, context_t *ctl,
 context_t *toReplace, context_t **ppStoreContext, BOOL use_link)
{
    BOOL ret;
    context_t *childContext = NULL;
    WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;

    ret = CRYPT_CollectionAddContext(cs, offsetof(store_vtbl_t, ctls),
     ctl, toReplace, &childContext);
    if (ppStoreContext && childContext)
    {
        WINE_STORE_LIST_ENTRY *storeEntry = childContext->u.ptr;
        ctl_t *context = (ctl_t*)CRYPT_CollectionCreateContextFromChild(cs, storeEntry,
         childContext);

        *ppStoreContext = &context->base;
    }
    if (childContext)
        Context_Release(childContext);
    return ret;
}

static context_t *Collection_enumCTL(WINECRYPT_CERTSTORE *store, context_t *prev)
{
    WINE_COLLECTIONSTORE *cs = (WINE_COLLECTIONSTORE*)store;
    void *ret;

    TRACE("(%p, %p)\n", store, prev);

    EnterCriticalSection(&cs->cs);
    if (prev)
    {
        WINE_STORE_LIST_ENTRY *storeEntry = prev->u.ptr;

        ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
         &storeEntry->store->vtbl->ctls, prev);
    }
    else
    {
        if (!list_empty(&cs->stores))
        {
            WINE_STORE_LIST_ENTRY *storeEntry = LIST_ENTRY(cs->stores.next,
             WINE_STORE_LIST_ENTRY, entry);

            ret = CRYPT_CollectionAdvanceEnum(cs, storeEntry,
             &storeEntry->store->vtbl->ctls, NULL);
        }
        else
        {
            SetLastError(CRYPT_E_NOT_FOUND);
            ret = NULL;
        }
    }
    LeaveCriticalSection(&cs->cs);
    TRACE("returning %p\n", ret);
    return ret;
}

static BOOL Collection_deleteCTL(WINECRYPT_CERTSTORE *store, context_t *context)
{
    ctl_t *ctl = (ctl_t*)context, *linked;

    TRACE("(%p, %p)\n", store, ctl);

    linked = (ctl_t*)context->linked;
    return CertDeleteCTLFromStore(&linked->ctx);
}

static BOOL Collection_control(WINECRYPT_CERTSTORE *cert_store, DWORD dwFlags,
 DWORD dwCtrlType, void const *pvCtrlPara)
{
    BOOL ret;
    WINE_COLLECTIONSTORE *store = (WINE_COLLECTIONSTORE*)cert_store;
    WINE_STORE_LIST_ENTRY *entry;

    TRACE("(%p, %08x, %d, %p)\n", cert_store, dwFlags, dwCtrlType, pvCtrlPara);

    if (!store)
        return TRUE;
    if (store->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (store->hdr.type != StoreTypeCollection)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }

    ret = TRUE;
    EnterCriticalSection(&store->cs);
    LIST_FOR_EACH_ENTRY(entry, &store->stores, WINE_STORE_LIST_ENTRY, entry)
    {
        if (entry->store->vtbl->control)
        {
            ret = entry->store->vtbl->control(entry->store, dwFlags, dwCtrlType, pvCtrlPara);
            if (!ret)
                break;
        }
    }
    LeaveCriticalSection(&store->cs);
    return ret;
}

static const store_vtbl_t CollectionStoreVtbl = {
    Collection_addref,
    Collection_release,
    Collection_releaseContext,
    Collection_control,
    {
        Collection_addCert,
        Collection_enumCert,
        Collection_deleteCert
    }, {
        Collection_addCRL,
        Collection_enumCRL,
        Collection_deleteCRL
    }, {
        Collection_addCTL,
        Collection_enumCTL,
        Collection_deleteCTL
    }
};

WINECRYPT_CERTSTORE *CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv,
 DWORD dwFlags, const void *pvPara)
{
    WINE_COLLECTIONSTORE *store;

    if (dwFlags & CERT_STORE_DELETE_FLAG)
    {
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
        store = NULL;
    }
    else
    {
        store = CryptMemAlloc(sizeof(WINE_COLLECTIONSTORE));
        if (store)
        {
            memset(store, 0, sizeof(WINE_COLLECTIONSTORE));
            CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeCollection, &CollectionStoreVtbl);
            InitializeCriticalSection(&store->cs);
            store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs");
            list_init(&store->stores);
        }
    }
    return (WINECRYPT_CERTSTORE*)store;
}

BOOL WINAPI CertAddStoreToCollection(HCERTSTORE hCollectionStore,
 HCERTSTORE hSiblingStore, DWORD dwUpdateFlags, DWORD dwPriority)
{
    WINE_COLLECTIONSTORE *collection = hCollectionStore;
    WINECRYPT_CERTSTORE *sibling = hSiblingStore;
    WINE_STORE_LIST_ENTRY *entry;
    BOOL ret;

    TRACE("(%p, %p, %08x, %d)\n", hCollectionStore, hSiblingStore,
     dwUpdateFlags, dwPriority);

    if (!collection || !sibling)
        return TRUE;
    if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (collection->hdr.type != StoreTypeCollection)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }

    entry = CryptMemAlloc(sizeof(WINE_STORE_LIST_ENTRY));
    if (entry)
    {
        InterlockedIncrement(&sibling->ref);
        TRACE("sibling %p's ref count is %d\n", sibling, sibling->ref);
        entry->store = sibling;
        entry->dwUpdateFlags = dwUpdateFlags;
        entry->dwPriority = dwPriority;
        list_init(&entry->entry);
        TRACE("%p: adding %p, priority %d\n", collection, entry, dwPriority);
        EnterCriticalSection(&collection->cs);
        if (dwPriority)
        {
            WINE_STORE_LIST_ENTRY *cursor;
            BOOL added = FALSE;

            LIST_FOR_EACH_ENTRY(cursor, &collection->stores,
             WINE_STORE_LIST_ENTRY, entry)
            {
                if (cursor->dwPriority < dwPriority)
                {
                    list_add_before(&cursor->entry, &entry->entry);
                    added = TRUE;
                    break;
                }
            }
            if (!added)
                list_add_tail(&collection->stores, &entry->entry);
        }
        else
            list_add_tail(&collection->stores, &entry->entry);
        LeaveCriticalSection(&collection->cs);
        ret = TRUE;
    }
    else
        ret = FALSE;
    return ret;
}

void WINAPI CertRemoveStoreFromCollection(HCERTSTORE hCollectionStore,
 HCERTSTORE hSiblingStore)
{
    WINE_COLLECTIONSTORE *collection = hCollectionStore;
    WINECRYPT_CERTSTORE *sibling = hSiblingStore;
    WINE_STORE_LIST_ENTRY *store, *next;

    TRACE("(%p, %p)\n", hCollectionStore, hSiblingStore);

    if (!collection || !sibling)
        return;
    if (collection->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
    {
        SetLastError(E_INVALIDARG);
        return;
    }
    if (collection->hdr.type != StoreTypeCollection)
        return;
    if (sibling->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
    {
        SetLastError(E_INVALIDARG);
        return;
    }
    EnterCriticalSection(&collection->cs);
    LIST_FOR_EACH_ENTRY_SAFE(store, next, &collection->stores,
     WINE_STORE_LIST_ENTRY, entry)
    {
        if (store->store == sibling)
        {
            list_remove(&store->entry);
            CertCloseStore(store->store, 0);
            CryptMemFree(store);
            break;
        }
    }
    LeaveCriticalSection(&collection->cs);
}
