/*
 * standard IPropertyStore implementation
 *
 * Copyright 2012 Vincent Povirk 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
 */

#define COBJMACROS
#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "rpcproxy.h"
#include "propsys.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/list.h"

#include "initguid.h"
#include "propsys_private.h"

DEFINE_GUID(FMTID_NamedProperties, 0xd5cdd505, 0x2e9c, 0x101b, 0x93, 0x97, 0x08, 0x00, 0x2b, 0x2c, 0xf9, 0xae);

WINE_DEFAULT_DEBUG_CHANNEL(propsys);

typedef struct {
    struct list entry;
    DWORD pid;
    PROPVARIANT propvar;
    PSC_STATE state;
} propstore_value;

typedef struct {
    struct list entry;
    GUID fmtid;
    struct list values; /* list of struct propstore_value */
    DWORD count;
} propstore_format;

typedef struct {
    IPropertyStoreCache IPropertyStoreCache_iface;
    LONG ref;
    CRITICAL_SECTION lock;
    struct list formats; /* list of struct propstore_format */
} PropertyStore;

static inline PropertyStore *impl_from_IPropertyStoreCache(IPropertyStoreCache *iface)
{
    return CONTAINING_RECORD(iface, PropertyStore, IPropertyStoreCache_iface);
}

static HRESULT WINAPI PropertyStore_QueryInterface(IPropertyStoreCache *iface, REFIID iid,
    void **ppv)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IPropertyStore, iid) ||
        IsEqualIID(&IID_IPropertyStoreCache, iid))
    {
        *ppv = &This->IPropertyStoreCache_iface;
    }
    else
    {
        FIXME("No interface for %s\n", debugstr_guid(iid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI PropertyStore_AddRef(IPropertyStoreCache *iface)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static void destroy_format(propstore_format *format)
{
    propstore_value *cursor, *cursor2;
    LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &format->values, propstore_value, entry)
    {
        PropVariantClear(&cursor->propvar);
        HeapFree(GetProcessHeap(), 0, cursor);
    }
    HeapFree(GetProcessHeap(), 0, format);
}

static ULONG WINAPI PropertyStore_Release(IPropertyStoreCache *iface)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        propstore_format *cursor, *cursor2;
        This->lock.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->lock);
        LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->formats, propstore_format, entry)
            destroy_format(cursor);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI PropertyStore_GetCount(IPropertyStoreCache *iface,
    DWORD *cProps)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_format *format;

    TRACE("%p,%p\n", iface, cProps);

    if (!cProps)
        return E_POINTER;

    *cProps = 0;

    EnterCriticalSection(&This->lock);

    LIST_FOR_EACH_ENTRY(format, &This->formats, propstore_format, entry)
        *cProps += format->count;

    LeaveCriticalSection(&This->lock);

    return S_OK;
}

static HRESULT WINAPI PropertyStore_GetAt(IPropertyStoreCache *iface,
    DWORD iProp, PROPERTYKEY *pkey)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_format *format=NULL, *format_candidate;
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%d,%p\n", iface, iProp, pkey);

    if (!pkey)
        return E_POINTER;

    EnterCriticalSection(&This->lock);

    LIST_FOR_EACH_ENTRY(format_candidate, &This->formats, propstore_format, entry)
    {
        if (format_candidate->count > iProp)
        {
            format = format_candidate;
            pkey->fmtid = format->fmtid;
            break;
        }

        iProp -= format_candidate->count;
    }

    if (format)
    {
        LIST_FOR_EACH_ENTRY(value, &format->values, propstore_value, entry)
        {
            if (iProp == 0)
            {
                pkey->pid = value->pid;
                break;
            }

            iProp--;
        }

        hr = S_OK;
    }
    else
        hr = E_INVALIDARG;

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT PropertyStore_LookupValue(PropertyStore *This, REFPROPERTYKEY key,
                                         BOOL insert, propstore_value **result)
{
    propstore_format *format=NULL, *format_candidate;
    propstore_value *value=NULL, *value_candidate;

    if (IsEqualGUID(&key->fmtid, &FMTID_NamedProperties))
    {
        /* This is used in the property store format [MS-PROPSTORE]
         * for named values and probably gets special treatment. */
        ERR("don't know how to handle FMTID_NamedProperties\n");
        return E_FAIL;
    }

    LIST_FOR_EACH_ENTRY(format_candidate, &This->formats, propstore_format, entry)
    {
        if (IsEqualGUID(&format_candidate->fmtid, &key->fmtid))
        {
            format = format_candidate;
            break;
        }
    }

    if (!format)
    {
        if (!insert)
            return TYPE_E_ELEMENTNOTFOUND;

        format = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*format));
        if (!format)
            return E_OUTOFMEMORY;

        format->fmtid = key->fmtid;
        list_init(&format->values);
        list_add_tail(&This->formats, &format->entry);
    }

    LIST_FOR_EACH_ENTRY(value_candidate, &format->values, propstore_value, entry)
    {
        if (value_candidate->pid == key->pid)
        {
            value = value_candidate;
            break;
        }
    }

    if (!value)
    {
        if (!insert)
            return TYPE_E_ELEMENTNOTFOUND;

        value = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*value));
        if (!value)
            return E_OUTOFMEMORY;

        value->pid = key->pid;
        list_add_tail(&format->values, &value->entry);
        format->count++;
    }

    *result = value;

    return S_OK;
}

static HRESULT WINAPI PropertyStore_GetValue(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, PROPVARIANT *pv)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%p,%p\n", iface, key, pv);

    if (!pv)
        return E_POINTER;

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, FALSE, &value);

    if (SUCCEEDED(hr))
        hr = PropVariantCopy(pv, &value->propvar);
    else if (hr == TYPE_E_ELEMENTNOTFOUND)
    {
        PropVariantInit(pv);
        hr = S_OK;
    }

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT WINAPI PropertyStore_SetValue(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, REFPROPVARIANT propvar)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;
    PROPVARIANT temp;

    TRACE("%p,%p,%p\n", iface, key, propvar);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, TRUE, &value);

    if (SUCCEEDED(hr))
        hr = PropVariantCopy(&temp, propvar);

    if (SUCCEEDED(hr))
    {
        PropVariantClear(&value->propvar);
        value->propvar = temp;
    }

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT WINAPI PropertyStore_Commit(IPropertyStoreCache *iface)
{
    FIXME("%p: stub\n", iface);
    return S_OK;
}

static HRESULT WINAPI PropertyStore_GetState(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, PSC_STATE *pstate)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%p,%p\n", iface, key, pstate);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, FALSE, &value);

    if (SUCCEEDED(hr))
        *pstate = value->state;

    LeaveCriticalSection(&This->lock);

    if (FAILED(hr))
        *pstate = PSC_NORMAL;

    return hr;
}

static HRESULT WINAPI PropertyStore_GetValueAndState(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, PROPVARIANT *ppropvar, PSC_STATE *pstate)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%p,%p,%p\n", iface, key, ppropvar, pstate);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, FALSE, &value);

    if (SUCCEEDED(hr))
        hr = PropVariantCopy(ppropvar, &value->propvar);

    if (SUCCEEDED(hr))
        *pstate = value->state;

    LeaveCriticalSection(&This->lock);

    if (FAILED(hr))
    {
        PropVariantInit(ppropvar);
        *pstate = PSC_NORMAL;
    }

    return hr;
}

static HRESULT WINAPI PropertyStore_SetState(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, PSC_STATE pstate)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;

    TRACE("%p,%p,%d\n", iface, key, pstate);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, FALSE, &value);

    if (SUCCEEDED(hr))
        value->state = pstate;

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT WINAPI PropertyStore_SetValueAndState(IPropertyStoreCache *iface,
    REFPROPERTYKEY key, const PROPVARIANT *ppropvar, PSC_STATE state)
{
    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
    propstore_value *value;
    HRESULT hr;
    PROPVARIANT temp;

    TRACE("%p,%p,%p,%d\n", iface, key, ppropvar, state);

    EnterCriticalSection(&This->lock);

    hr = PropertyStore_LookupValue(This, key, TRUE, &value);

    if (SUCCEEDED(hr))
        hr = PropVariantCopy(&temp, ppropvar);

    if (SUCCEEDED(hr))
    {
        PropVariantClear(&value->propvar);
        value->propvar = temp;
        value->state = state;
    }

    LeaveCriticalSection(&This->lock);

    return hr;
}

static const IPropertyStoreCacheVtbl PropertyStore_Vtbl = {
    PropertyStore_QueryInterface,
    PropertyStore_AddRef,
    PropertyStore_Release,
    PropertyStore_GetCount,
    PropertyStore_GetAt,
    PropertyStore_GetValue,
    PropertyStore_SetValue,
    PropertyStore_Commit,
    PropertyStore_GetState,
    PropertyStore_GetValueAndState,
    PropertyStore_SetState,
    PropertyStore_SetValueAndState
};

HRESULT PropertyStore_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
    PropertyStore *This;
    HRESULT ret;

    TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);

    *ppv = NULL;

    if (pUnkOuter) return CLASS_E_NOAGGREGATION;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(PropertyStore));
    if (!This) return E_OUTOFMEMORY;

    This->IPropertyStoreCache_iface.lpVtbl = &PropertyStore_Vtbl;
    This->ref = 1;
    InitializeCriticalSection(&This->lock);
    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PropertyStore.lock");
    list_init(&This->formats);

    ret = IPropertyStoreCache_QueryInterface(&This->IPropertyStoreCache_iface, iid, ppv);
    IPropertyStoreCache_Release(&This->IPropertyStoreCache_iface);

    return ret;
}
